{
 "cells": [
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-25T10:44:44.414423Z",
     "start_time": "2025-01-25T10:44:42.204787Z"
    }
   },
   "source": [
    "import matplotlib as mpl\n",
    "import matplotlib.pyplot as plt\n",
    "%matplotlib inline\n",
    "import numpy as np\n",
    "import sklearn\n",
    "import pandas as pd\n",
    "import os\n",
    "import sys\n",
    "import time\n",
    "from tqdm.auto import tqdm\n",
    "import torch\n",
    "import torch.nn as nn\n",
    "import torch.nn.functional as F\n",
    "\n",
    "print(sys.version_info)\n",
    "for module in mpl, np, pd, sklearn, torch:\n",
    "    print(module.__name__, module.__version__)\n",
    "    \n",
    "device = torch.device(\"cuda:0\") if torch.cuda.is_available() else torch.device(\"cpu\")\n",
    "print(device)\n"
   ],
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "sys.version_info(major=3, minor=12, micro=3, releaselevel='final', serial=0)\n",
      "matplotlib 3.10.0\n",
      "numpy 1.26.4\n",
      "pandas 2.2.3\n",
      "sklearn 1.6.1\n",
      "torch 2.5.1+cpu\n",
      "cpu\n"
     ]
    }
   ],
   "execution_count": 9
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 准备数据"
   ]
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-25T08:38:32.157794Z",
     "start_time": "2025-01-25T08:38:30.570646Z"
    }
   },
   "source": [
    "from sklearn.datasets import fetch_california_housing\n",
    "\n",
    "housing = fetch_california_housing(data_home='data')\n",
    "print(housing.DESCR)\n",
    "print(housing.data.shape)\n",
    "print(housing.target.shape)"
   ],
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      ".. _california_housing_dataset:\n",
      "\n",
      "California Housing dataset\n",
      "--------------------------\n",
      "\n",
      "**Data Set Characteristics:**\n",
      "\n",
      ":Number of Instances: 20640\n",
      "\n",
      ":Number of Attributes: 8 numeric, predictive attributes and the target\n",
      "\n",
      ":Attribute Information:\n",
      "    - MedInc        median income in block group\n",
      "    - HouseAge      median house age in block group\n",
      "    - AveRooms      average number of rooms per household\n",
      "    - AveBedrms     average number of bedrooms per household\n",
      "    - Population    block group population\n",
      "    - AveOccup      average number of household members\n",
      "    - Latitude      block group latitude\n",
      "    - Longitude     block group longitude\n",
      "\n",
      ":Missing Attribute Values: None\n",
      "\n",
      "This dataset was obtained from the StatLib repository.\n",
      "https://www.dcc.fc.up.pt/~ltorgo/Regression/cal_housing.html\n",
      "\n",
      "The target variable is the median house value for California districts,\n",
      "expressed in hundreds of thousands of dollars ($100,000).\n",
      "\n",
      "This dataset was derived from the 1990 U.S. census, using one row per census\n",
      "block group. A block group is the smallest geographical unit for which the U.S.\n",
      "Census Bureau publishes sample data (a block group typically has a population\n",
      "of 600 to 3,000 people).\n",
      "\n",
      "A household is a group of people residing within a home. Since the average\n",
      "number of rooms and bedrooms in this dataset are provided per household, these\n",
      "columns may take surprisingly large values for block groups with few households\n",
      "and many empty houses, such as vacation resorts.\n",
      "\n",
      "It can be downloaded/loaded using the\n",
      ":func:`sklearn.datasets.fetch_california_housing` function.\n",
      "\n",
      ".. rubric:: References\n",
      "\n",
      "- Pace, R. Kelley and Ronald Barry, Sparse Spatial Autoregressions,\n",
      "  Statistics and Probability Letters, 33 (1997) 291-297\n",
      "\n",
      "(20640, 8)\n",
      "(20640,)\n"
     ]
    }
   ],
   "execution_count": 1
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-25T08:38:32.164986Z",
     "start_time": "2025-01-25T08:38:32.158791Z"
    }
   },
   "source": [
    "# print(housing.data[0:5])\n",
    "import pprint  #打印的格式比较 好看\n",
    "\n",
    "pprint.pprint(housing.data[0:2])\n",
    "print('-'*50)\n",
    "pprint.pprint(housing.target[0:2])"
   ],
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "array([[ 8.32520000e+00,  4.10000000e+01,  6.98412698e+00,\n",
      "         1.02380952e+00,  3.22000000e+02,  2.55555556e+00,\n",
      "         3.78800000e+01, -1.22230000e+02],\n",
      "       [ 8.30140000e+00,  2.10000000e+01,  6.23813708e+00,\n",
      "         9.71880492e-01,  2.40100000e+03,  2.10984183e+00,\n",
      "         3.78600000e+01, -1.22220000e+02]])\n",
      "--------------------------------------------------\n",
      "array([4.526, 3.585])\n"
     ]
    }
   ],
   "execution_count": 2
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "### 预处理数据：拆分训练集、验证集、测试集"
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-25T10:37:41.834937Z",
     "start_time": "2025-01-25T10:37:41.747354Z"
    }
   },
   "source": [
    "from sklearn.model_selection import train_test_split\n",
    "\n",
    "# 拆分训练集和测试集，random_state是随机种子,同样的随机数种子，是为了得到同样的随机值\n",
    "x_train_all, x_test, y_train_all, y_test = train_test_split(   #默认是0.25\n",
    "    housing.data, housing.target, random_state = 7)\n",
    "# 拆分训练集和验证集\n",
    "x_train, x_valid, y_train, y_valid = train_test_split(\n",
    "    x_train_all, y_train_all, random_state = 11)\n",
    "\n",
    "# 训练集\n",
    "print(x_train.shape, y_train.shape)\n",
    "# 验证集\n",
    "print(x_valid.shape, y_valid.shape)\n",
    "# 测试集\n",
    "print(x_test.shape, y_test.shape)\n",
    "\n",
    "# 把3个数据集都放到字典里，每个是列表，里面是ndarray类型的数据\n",
    "dataset_maps = {\n",
    "    \"train\": [x_train, y_train],\n",
    "    \"valid\": [x_valid, y_valid],\n",
    "    \"test\": [x_test, y_test],\n",
    "}"
   ],
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(11610, 8) (11610,)\n",
      "(3870, 8) (3870,)\n",
      "(5160, 8) (5160,)\n"
     ]
    }
   ],
   "execution_count": 3
  },
  {
   "cell_type": "code",
   "source": [
    "print(type(x_train))\n",
    "print(type(dataset_maps[\"train\"]))"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-01-25T10:42:07.823573Z",
     "start_time": "2025-01-25T10:42:07.819836Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'numpy.ndarray'>\n",
      "<class 'list'>\n"
     ]
    }
   ],
   "execution_count": 6
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-25T10:44:09.120478Z",
     "start_time": "2025-01-25T10:44:09.111288Z"
    }
   },
   "source": [
    "from sklearn.preprocessing import StandardScaler\n",
    "\n",
    "scaler = StandardScaler() # 标准化\n",
    "# 这里只fit，不transform，因为后面要用transform\n",
    "scaler.fit(x_train) # fit和fit_transform的区别，fit是计算均值和方差，fit_transform是先fit，然后transform"
   ],
   "outputs": [
    {
     "data": {
      "text/plain": [
       "StandardScaler()"
      ],
      "text/html": [
       "<style>#sk-container-id-1 {\n",
       "  /* Definition of color scheme common for light and dark mode */\n",
       "  --sklearn-color-text: #000;\n",
       "  --sklearn-color-text-muted: #666;\n",
       "  --sklearn-color-line: gray;\n",
       "  /* Definition of color scheme for unfitted estimators */\n",
       "  --sklearn-color-unfitted-level-0: #fff5e6;\n",
       "  --sklearn-color-unfitted-level-1: #f6e4d2;\n",
       "  --sklearn-color-unfitted-level-2: #ffe0b3;\n",
       "  --sklearn-color-unfitted-level-3: chocolate;\n",
       "  /* Definition of color scheme for fitted estimators */\n",
       "  --sklearn-color-fitted-level-0: #f0f8ff;\n",
       "  --sklearn-color-fitted-level-1: #d4ebff;\n",
       "  --sklearn-color-fitted-level-2: #b3dbfd;\n",
       "  --sklearn-color-fitted-level-3: cornflowerblue;\n",
       "\n",
       "  /* Specific color for light theme */\n",
       "  --sklearn-color-text-on-default-background: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, black)));\n",
       "  --sklearn-color-background: var(--sg-background-color, var(--theme-background, var(--jp-layout-color0, white)));\n",
       "  --sklearn-color-border-box: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, black)));\n",
       "  --sklearn-color-icon: #696969;\n",
       "\n",
       "  @media (prefers-color-scheme: dark) {\n",
       "    /* Redefinition of color scheme for dark theme */\n",
       "    --sklearn-color-text-on-default-background: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, white)));\n",
       "    --sklearn-color-background: var(--sg-background-color, var(--theme-background, var(--jp-layout-color0, #111)));\n",
       "    --sklearn-color-border-box: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, white)));\n",
       "    --sklearn-color-icon: #878787;\n",
       "  }\n",
       "}\n",
       "\n",
       "#sk-container-id-1 {\n",
       "  color: var(--sklearn-color-text);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 pre {\n",
       "  padding: 0;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 input.sk-hidden--visually {\n",
       "  border: 0;\n",
       "  clip: rect(1px 1px 1px 1px);\n",
       "  clip: rect(1px, 1px, 1px, 1px);\n",
       "  height: 1px;\n",
       "  margin: -1px;\n",
       "  overflow: hidden;\n",
       "  padding: 0;\n",
       "  position: absolute;\n",
       "  width: 1px;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-dashed-wrapped {\n",
       "  border: 1px dashed var(--sklearn-color-line);\n",
       "  margin: 0 0.4em 0.5em 0.4em;\n",
       "  box-sizing: border-box;\n",
       "  padding-bottom: 0.4em;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-container {\n",
       "  /* jupyter's `normalize.less` sets `[hidden] { display: none; }`\n",
       "     but bootstrap.min.css set `[hidden] { display: none !important; }`\n",
       "     so we also need the `!important` here to be able to override the\n",
       "     default hidden behavior on the sphinx rendered scikit-learn.org.\n",
       "     See: https://github.com/scikit-learn/scikit-learn/issues/21755 */\n",
       "  display: inline-block !important;\n",
       "  position: relative;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-text-repr-fallback {\n",
       "  display: none;\n",
       "}\n",
       "\n",
       "div.sk-parallel-item,\n",
       "div.sk-serial,\n",
       "div.sk-item {\n",
       "  /* draw centered vertical line to link estimators */\n",
       "  background-image: linear-gradient(var(--sklearn-color-text-on-default-background), var(--sklearn-color-text-on-default-background));\n",
       "  background-size: 2px 100%;\n",
       "  background-repeat: no-repeat;\n",
       "  background-position: center center;\n",
       "}\n",
       "\n",
       "/* Parallel-specific style estimator block */\n",
       "\n",
       "#sk-container-id-1 div.sk-parallel-item::after {\n",
       "  content: \"\";\n",
       "  width: 100%;\n",
       "  border-bottom: 2px solid var(--sklearn-color-text-on-default-background);\n",
       "  flex-grow: 1;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-parallel {\n",
       "  display: flex;\n",
       "  align-items: stretch;\n",
       "  justify-content: center;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "  position: relative;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-parallel-item {\n",
       "  display: flex;\n",
       "  flex-direction: column;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-parallel-item:first-child::after {\n",
       "  align-self: flex-end;\n",
       "  width: 50%;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-parallel-item:last-child::after {\n",
       "  align-self: flex-start;\n",
       "  width: 50%;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-parallel-item:only-child::after {\n",
       "  width: 0;\n",
       "}\n",
       "\n",
       "/* Serial-specific style estimator block */\n",
       "\n",
       "#sk-container-id-1 div.sk-serial {\n",
       "  display: flex;\n",
       "  flex-direction: column;\n",
       "  align-items: center;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "  padding-right: 1em;\n",
       "  padding-left: 1em;\n",
       "}\n",
       "\n",
       "\n",
       "/* Toggleable style: style used for estimator/Pipeline/ColumnTransformer box that is\n",
       "clickable and can be expanded/collapsed.\n",
       "- Pipeline and ColumnTransformer use this feature and define the default style\n",
       "- Estimators will overwrite some part of the style using the `sk-estimator` class\n",
       "*/\n",
       "\n",
       "/* Pipeline and ColumnTransformer style (default) */\n",
       "\n",
       "#sk-container-id-1 div.sk-toggleable {\n",
       "  /* Default theme specific background. It is overwritten whether we have a\n",
       "  specific estimator or a Pipeline/ColumnTransformer */\n",
       "  background-color: var(--sklearn-color-background);\n",
       "}\n",
       "\n",
       "/* Toggleable label */\n",
       "#sk-container-id-1 label.sk-toggleable__label {\n",
       "  cursor: pointer;\n",
       "  display: flex;\n",
       "  width: 100%;\n",
       "  margin-bottom: 0;\n",
       "  padding: 0.5em;\n",
       "  box-sizing: border-box;\n",
       "  text-align: center;\n",
       "  align-items: start;\n",
       "  justify-content: space-between;\n",
       "  gap: 0.5em;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 label.sk-toggleable__label .caption {\n",
       "  font-size: 0.6rem;\n",
       "  font-weight: lighter;\n",
       "  color: var(--sklearn-color-text-muted);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 label.sk-toggleable__label-arrow:before {\n",
       "  /* Arrow on the left of the label */\n",
       "  content: \"▸\";\n",
       "  float: left;\n",
       "  margin-right: 0.25em;\n",
       "  color: var(--sklearn-color-icon);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 label.sk-toggleable__label-arrow:hover:before {\n",
       "  color: var(--sklearn-color-text);\n",
       "}\n",
       "\n",
       "/* Toggleable content - dropdown */\n",
       "\n",
       "#sk-container-id-1 div.sk-toggleable__content {\n",
       "  max-height: 0;\n",
       "  max-width: 0;\n",
       "  overflow: hidden;\n",
       "  text-align: left;\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-toggleable__content.fitted {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-toggleable__content pre {\n",
       "  margin: 0.2em;\n",
       "  border-radius: 0.25em;\n",
       "  color: var(--sklearn-color-text);\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-toggleable__content.fitted pre {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 input.sk-toggleable__control:checked~div.sk-toggleable__content {\n",
       "  /* Expand drop-down */\n",
       "  max-height: 200px;\n",
       "  max-width: 100%;\n",
       "  overflow: auto;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 input.sk-toggleable__control:checked~label.sk-toggleable__label-arrow:before {\n",
       "  content: \"▾\";\n",
       "}\n",
       "\n",
       "/* Pipeline/ColumnTransformer-specific style */\n",
       "\n",
       "#sk-container-id-1 div.sk-label input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
       "  color: var(--sklearn-color-text);\n",
       "  background-color: var(--sklearn-color-unfitted-level-2);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-label.fitted input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
       "  background-color: var(--sklearn-color-fitted-level-2);\n",
       "}\n",
       "\n",
       "/* Estimator-specific style */\n",
       "\n",
       "/* Colorize estimator box */\n",
       "#sk-container-id-1 div.sk-estimator input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-2);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-estimator.fitted input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-2);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-label label.sk-toggleable__label,\n",
       "#sk-container-id-1 div.sk-label label {\n",
       "  /* The background is the default theme color */\n",
       "  color: var(--sklearn-color-text-on-default-background);\n",
       "}\n",
       "\n",
       "/* On hover, darken the color of the background */\n",
       "#sk-container-id-1 div.sk-label:hover label.sk-toggleable__label {\n",
       "  color: var(--sklearn-color-text);\n",
       "  background-color: var(--sklearn-color-unfitted-level-2);\n",
       "}\n",
       "\n",
       "/* Label box, darken color on hover, fitted */\n",
       "#sk-container-id-1 div.sk-label.fitted:hover label.sk-toggleable__label.fitted {\n",
       "  color: var(--sklearn-color-text);\n",
       "  background-color: var(--sklearn-color-fitted-level-2);\n",
       "}\n",
       "\n",
       "/* Estimator label */\n",
       "\n",
       "#sk-container-id-1 div.sk-label label {\n",
       "  font-family: monospace;\n",
       "  font-weight: bold;\n",
       "  display: inline-block;\n",
       "  line-height: 1.2em;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-label-container {\n",
       "  text-align: center;\n",
       "}\n",
       "\n",
       "/* Estimator-specific */\n",
       "#sk-container-id-1 div.sk-estimator {\n",
       "  font-family: monospace;\n",
       "  border: 1px dotted var(--sklearn-color-border-box);\n",
       "  border-radius: 0.25em;\n",
       "  box-sizing: border-box;\n",
       "  margin-bottom: 0.5em;\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-estimator.fitted {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-0);\n",
       "}\n",
       "\n",
       "/* on hover */\n",
       "#sk-container-id-1 div.sk-estimator:hover {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-2);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-estimator.fitted:hover {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-2);\n",
       "}\n",
       "\n",
       "/* Specification for estimator info (e.g. \"i\" and \"?\") */\n",
       "\n",
       "/* Common style for \"i\" and \"?\" */\n",
       "\n",
       ".sk-estimator-doc-link,\n",
       "a:link.sk-estimator-doc-link,\n",
       "a:visited.sk-estimator-doc-link {\n",
       "  float: right;\n",
       "  font-size: smaller;\n",
       "  line-height: 1em;\n",
       "  font-family: monospace;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "  border-radius: 1em;\n",
       "  height: 1em;\n",
       "  width: 1em;\n",
       "  text-decoration: none !important;\n",
       "  margin-left: 0.5em;\n",
       "  text-align: center;\n",
       "  /* unfitted */\n",
       "  border: var(--sklearn-color-unfitted-level-1) 1pt solid;\n",
       "  color: var(--sklearn-color-unfitted-level-1);\n",
       "}\n",
       "\n",
       ".sk-estimator-doc-link.fitted,\n",
       "a:link.sk-estimator-doc-link.fitted,\n",
       "a:visited.sk-estimator-doc-link.fitted {\n",
       "  /* fitted */\n",
       "  border: var(--sklearn-color-fitted-level-1) 1pt solid;\n",
       "  color: var(--sklearn-color-fitted-level-1);\n",
       "}\n",
       "\n",
       "/* On hover */\n",
       "div.sk-estimator:hover .sk-estimator-doc-link:hover,\n",
       ".sk-estimator-doc-link:hover,\n",
       "div.sk-label-container:hover .sk-estimator-doc-link:hover,\n",
       ".sk-estimator-doc-link:hover {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-3);\n",
       "  color: var(--sklearn-color-background);\n",
       "  text-decoration: none;\n",
       "}\n",
       "\n",
       "div.sk-estimator.fitted:hover .sk-estimator-doc-link.fitted:hover,\n",
       ".sk-estimator-doc-link.fitted:hover,\n",
       "div.sk-label-container:hover .sk-estimator-doc-link.fitted:hover,\n",
       ".sk-estimator-doc-link.fitted:hover {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-3);\n",
       "  color: var(--sklearn-color-background);\n",
       "  text-decoration: none;\n",
       "}\n",
       "\n",
       "/* Span, style for the box shown on hovering the info icon */\n",
       ".sk-estimator-doc-link span {\n",
       "  display: none;\n",
       "  z-index: 9999;\n",
       "  position: relative;\n",
       "  font-weight: normal;\n",
       "  right: .2ex;\n",
       "  padding: .5ex;\n",
       "  margin: .5ex;\n",
       "  width: min-content;\n",
       "  min-width: 20ex;\n",
       "  max-width: 50ex;\n",
       "  color: var(--sklearn-color-text);\n",
       "  box-shadow: 2pt 2pt 4pt #999;\n",
       "  /* unfitted */\n",
       "  background: var(--sklearn-color-unfitted-level-0);\n",
       "  border: .5pt solid var(--sklearn-color-unfitted-level-3);\n",
       "}\n",
       "\n",
       ".sk-estimator-doc-link.fitted span {\n",
       "  /* fitted */\n",
       "  background: var(--sklearn-color-fitted-level-0);\n",
       "  border: var(--sklearn-color-fitted-level-3);\n",
       "}\n",
       "\n",
       ".sk-estimator-doc-link:hover span {\n",
       "  display: block;\n",
       "}\n",
       "\n",
       "/* \"?\"-specific style due to the `<a>` HTML tag */\n",
       "\n",
       "#sk-container-id-1 a.estimator_doc_link {\n",
       "  float: right;\n",
       "  font-size: 1rem;\n",
       "  line-height: 1em;\n",
       "  font-family: monospace;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "  border-radius: 1rem;\n",
       "  height: 1rem;\n",
       "  width: 1rem;\n",
       "  text-decoration: none;\n",
       "  /* unfitted */\n",
       "  color: var(--sklearn-color-unfitted-level-1);\n",
       "  border: var(--sklearn-color-unfitted-level-1) 1pt solid;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 a.estimator_doc_link.fitted {\n",
       "  /* fitted */\n",
       "  border: var(--sklearn-color-fitted-level-1) 1pt solid;\n",
       "  color: var(--sklearn-color-fitted-level-1);\n",
       "}\n",
       "\n",
       "/* On hover */\n",
       "#sk-container-id-1 a.estimator_doc_link:hover {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-3);\n",
       "  color: var(--sklearn-color-background);\n",
       "  text-decoration: none;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 a.estimator_doc_link.fitted:hover {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-3);\n",
       "}\n",
       "</style><div id=\"sk-container-id-1\" class=\"sk-top-container\"><div class=\"sk-text-repr-fallback\"><pre>StandardScaler()</pre><b>In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook. <br />On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.</b></div><div class=\"sk-container\" hidden><div class=\"sk-item\"><div class=\"sk-estimator fitted sk-toggleable\"><input class=\"sk-toggleable__control sk-hidden--visually\" id=\"sk-estimator-id-1\" type=\"checkbox\" checked><label for=\"sk-estimator-id-1\" class=\"sk-toggleable__label fitted sk-toggleable__label-arrow\"><div><div>StandardScaler</div></div><div><a class=\"sk-estimator-doc-link fitted\" rel=\"noreferrer\" target=\"_blank\" href=\"https://scikit-learn.org/1.6/modules/generated/sklearn.preprocessing.StandardScaler.html\">?<span>Documentation for StandardScaler</span></a><span class=\"sk-estimator-doc-link fitted\">i<span>Fitted</span></span></div></label><div class=\"sk-toggleable__content fitted\"><pre>StandardScaler()</pre></div> </div></div></div></div>"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 7
  },
  {
   "cell_type": "code",
   "source": "np.array(1).shape",
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-01-25T10:45:09.682577Z",
     "start_time": "2025-01-25T10:45:09.679149Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "()"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 12
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 构建数据集"
   ]
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-25T10:46:04.515186Z",
     "start_time": "2025-01-25T10:46:04.506408Z"
    }
   },
   "source": [
    "#构建私有数据集，就需要用如下方式\n",
    "from torch.utils.data import Dataset\n",
    "\n",
    "class HousingDataset(Dataset):\n",
    "    def __init__(self, mode='train'):\n",
    "        self.x, self.y = dataset_maps[mode] # x,y都是ndarray类型，这里dataset_maps是全局变量，也可以传参传进来\n",
    "        self.x = torch.from_numpy(scaler.transform(self.x)).float() # from_numpy将NumPy数组转换成PyTorch张量\n",
    "        self.y = torch.from_numpy(self.y).float().reshape(-1, 1) # 处理为多行1列的tensor类型，因为__getitem__切片时需要\n",
    "            \n",
    "    def __len__(self): #必须写\n",
    "        return len(self.x) #返回数据集的长度,0维的size\n",
    "    \n",
    "    # idx是索引，返回的是数据和标签，这里是一个样本\n",
    "    #重写后： for i in xxx:这样i能取出迭代器xxx里的东西\n",
    "    def __getitem__(self, idx): \n",
    "        return self.x[idx], self.y[idx]\n",
    "    \n",
    "#train_ds是dataset类型的数据，与前面例子的FashionMNIST类型一致\n",
    "train_ds = HousingDataset(\"train\")\n",
    "valid_ds = HousingDataset(\"valid\")\n",
    "test_ds = HousingDataset(\"test\")"
   ],
   "outputs": [],
   "execution_count": 14
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-25T10:46:05.013894Z",
     "start_time": "2025-01-25T10:46:05.010495Z"
    }
   },
   "cell_type": "code",
   "source": "print(type(train_ds))",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class '__main__.HousingDataset'>\n"
     ]
    }
   ],
   "execution_count": 15
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-25T10:48:14.575650Z",
     "start_time": "2025-01-25T10:48:14.561515Z"
    }
   },
   "source": [
    "train_ds[0]"
   ],
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(tensor([ 0.8015,  0.2722, -0.1162, -0.2023, -0.5431, -0.0210, -0.5898, -0.0824]),\n",
       " tensor([3.2260]))"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 16
  },
  {
   "cell_type": "code",
   "source": [
    "train_ds[0][0]"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-01-25T10:52:54.352602Z",
     "start_time": "2025-01-25T10:52:54.347691Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([ 0.8015,  0.2722, -0.1162, -0.2023, -0.5431, -0.0210, -0.5898, -0.0824])"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 17
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### DataLoader"
   ]
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-25T11:05:45.666730Z",
     "start_time": "2025-01-25T11:05:45.662729Z"
    }
   },
   "source": [
    "from torch.utils.data import DataLoader\n",
    "\n",
    "#放到DataLoader中的train_ds, valid_ds, test_ds都是dataset类型的数据\n",
    "batch_size = 16  # 可调的超参数，一般取16、32、64、128等\n",
    "train_loader = DataLoader(train_ds, batch_size=batch_size, shuffle=True)\n",
    "val_loader = DataLoader(valid_ds, batch_size=batch_size, shuffle=False)\n",
    "test_loader = DataLoader(test_ds, batch_size=batch_size, shuffle=False)"
   ],
   "outputs": [],
   "execution_count": 19
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 定义模型"
   ]
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-25T11:05:46.185661Z",
     "start_time": "2025-01-25T11:05:46.182324Z"
    }
   },
   "source": [
    "#回归模型我们只需要1个数\n",
    "\n",
    "class NeuralNetwork(nn.Module):\n",
    "    def __init__(self, input_dim=8):\n",
    "        super().__init__()\n",
    "        self.linear_relu_stack = nn.Sequential(  # 参数8*30+30+30*1+1=301\n",
    "            nn.Linear(input_dim, 30),\n",
    "            nn.ReLU(),\n",
    "            nn.Linear(30, 1)\n",
    "            )\n",
    "        \n",
    "    def forward(self, x):\n",
    "        # x.shape [batch size, 8]\n",
    "        logits = self.linear_relu_stack(x)\n",
    "        # logits.shape [batch size, 1]\n",
    "        return logits"
   ],
   "outputs": [],
   "execution_count": 20
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-25T11:05:46.670225Z",
     "start_time": "2025-01-25T11:05:46.666083Z"
    }
   },
   "source": [
    "class EarlyStopCallback:\n",
    "    def __init__(self, patience=5, min_delta=0.01):\n",
    "        \"\"\"\n",
    "\n",
    "        Args:\n",
    "            patience (int, optional): Number of epochs with no improvement after which training will be stopped.. Defaults to 5.\n",
    "            min_delta (float, optional): Minimum change in the monitored quantity to qualify as an improvement, i.e. an absolute \n",
    "                change of less than min_delta, will count as no improvement. Defaults to 0.01.\n",
    "        \"\"\"\n",
    "        self.patience = patience\n",
    "        self.min_delta = min_delta\n",
    "        self.best_metric = -1\n",
    "        self.counter = 0\n",
    "        \n",
    "    def __call__(self, metric):\n",
    "        if metric >= self.best_metric + self.min_delta:\n",
    "            # update best metric\n",
    "            self.best_metric = metric\n",
    "            # reset counter \n",
    "            self.counter = 0\n",
    "        else: \n",
    "            self.counter += 1\n",
    "            \n",
    "    @property\n",
    "    def early_stop(self):\n",
    "        return self.counter >= self.patience\n"
   ],
   "outputs": [],
   "execution_count": 21
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-25T11:05:47.162666Z",
     "start_time": "2025-01-25T11:05:47.158545Z"
    }
   },
   "source": [
    "from sklearn.metrics import accuracy_score\n",
    "\n",
    "@torch.no_grad()\n",
    "def evaluating(model, dataloader, loss_fct):\n",
    "    loss_list = []\n",
    "    for datas, labels in dataloader:\n",
    "        datas = datas.to(device)\n",
    "        labels = labels.to(device)\n",
    "        # 前向计算：只有损失没有准确率\n",
    "        logits = model(datas)\n",
    "        loss = loss_fct(logits, labels)         # 验证集损失\n",
    "        loss_list.append(loss.item())\n",
    "        \n",
    "    return np.mean(loss_list)\n"
   ],
   "outputs": [],
   "execution_count": 22
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-25T11:06:39.553328Z",
     "start_time": "2025-01-25T11:05:48.115802Z"
    }
   },
   "source": [
    "# 训练\n",
    "def training(\n",
    "    model, \n",
    "    train_loader, \n",
    "    val_loader, \n",
    "    epoch, \n",
    "    loss_fct, \n",
    "    optimizer,\n",
    "    early_stop_callback=None,\n",
    "    eval_step=500,\n",
    "    ):\n",
    "    record_dict = {\n",
    "        \"train\": [],\n",
    "        \"val\": []\n",
    "    }\n",
    "    \n",
    "    global_step = 0\n",
    "    model.train()\n",
    "    with tqdm(total=epoch * len(train_loader)) as pbar:\n",
    "        for epoch_id in range(epoch):  # 100*726=72600\n",
    "            # training\n",
    "            for datas, labels in train_loader:# 11610/16=726\n",
    "                datas = datas.to(device)\n",
    "                labels = labels.to(device)\n",
    "                # 梯度清空\n",
    "                optimizer.zero_grad()\n",
    "                # 模型前向计算\n",
    "                logits = model(datas) #得到预测值\n",
    "                # 计算损失\n",
    "                loss = loss_fct(logits, labels)\n",
    "                # 梯度回传\n",
    "                loss.backward()\n",
    "                # 调整优化器，包括学习率的变动等\n",
    "                optimizer.step()\n",
    " \n",
    "                loss = loss.cpu().item() #转为cpu类型，item()是取值\n",
    "                # record\n",
    "                \n",
    "                record_dict[\"train\"].append({\n",
    "                    \"loss\": loss, \"step\": global_step\n",
    "                })\n",
    "                \n",
    "                # evaluating\n",
    "                if global_step % eval_step == 0:\n",
    "                    model.eval()\n",
    "                    val_loss = evaluating(model, val_loader, loss_fct)\n",
    "                    record_dict[\"val\"].append({\n",
    "                        \"loss\": val_loss, \"step\": global_step\n",
    "                    })\n",
    "                    model.train()\n",
    "\n",
    "                    # 早停 Early Stop\n",
    "                    if early_stop_callback is not None:\n",
    "                         # 根据验证集的损失来实现早停\n",
    "                         # 加-是因为loss越小越好，同时early_stop用的是metric越来越好，为了复用\n",
    "                        early_stop_callback(-val_loss)\n",
    "                        if early_stop_callback.early_stop:\n",
    "                            print(f\"Early stop at epoch {epoch_id} / global_step {global_step}\")\n",
    "                            return record_dict\n",
    "                    \n",
    "                # update step\n",
    "                global_step += 1\n",
    "                pbar.update(1)\n",
    "                pbar.set_postfix({\"epoch\": epoch_id})\n",
    "        \n",
    "    return record_dict\n",
    "        \n",
    "\n",
    "epoch = 100\n",
    "model = NeuralNetwork()\n",
    "\n",
    "# 1. 定义损失函数 采用MSE损失,均方误差\n",
    "loss_fct = nn.MSELoss()\n",
    "# 2. 定义优化器 采用SGD\n",
    "optimizer = torch.optim.SGD(model.parameters(), lr=0.001, momentum=0.9)\n",
    "\n",
    "# 3. early stop\n",
    "early_stop_callback = EarlyStopCallback(patience=10, min_delta=1e-3)\n",
    "\n",
    "model = model.to(device)\n",
    "record = training(\n",
    "    model, \n",
    "    train_loader, \n",
    "    val_loader, \n",
    "    epoch, \n",
    "    loss_fct, \n",
    "    optimizer, \n",
    "    early_stop_callback=early_stop_callback,\n",
    "    eval_step=len(train_loader)\n",
    "    )"
   ],
   "outputs": [
    {
     "data": {
      "text/plain": [
       "  0%|          | 0/72600 [00:00<?, ?it/s]"
      ],
      "application/vnd.jupyter.widget-view+json": {
       "version_major": 2,
       "version_minor": 0,
       "model_id": "6cb05bb5e5454c279bd461c611dff023"
      }
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "IOPub message rate exceeded.\n",
      "The Jupyter server will temporarily stop sending output\n",
      "to the client in order to avoid crashing it.\n",
      "To change this limit, set the config variable\n",
      "`--ServerApp.iopub_msg_rate_limit`.\n",
      "\n",
      "Current values:\n",
      "ServerApp.iopub_msg_rate_limit=1000.0 (msgs/sec)\n",
      "ServerApp.rate_limit_window=3.0 (secs)\n",
      "\n",
      "IOPub message rate exceeded.\n",
      "The Jupyter server will temporarily stop sending output\n",
      "to the client in order to avoid crashing it.\n",
      "To change this limit, set the config variable\n",
      "`--ServerApp.iopub_msg_rate_limit`.\n",
      "\n",
      "Current values:\n",
      "ServerApp.iopub_msg_rate_limit=1000.0 (msgs/sec)\n",
      "ServerApp.rate_limit_window=3.0 (secs)\n",
      "\n",
      "IOPub message rate exceeded.\n",
      "The Jupyter server will temporarily stop sending output\n",
      "to the client in order to avoid crashing it.\n",
      "To change this limit, set the config variable\n",
      "`--ServerApp.iopub_msg_rate_limit`.\n",
      "\n",
      "Current values:\n",
      "ServerApp.iopub_msg_rate_limit=1000.0 (msgs/sec)\n",
      "ServerApp.rate_limit_window=3.0 (secs)\n",
      "\n",
      "IOPub message rate exceeded.\n",
      "The Jupyter server will temporarily stop sending output\n",
      "to the client in order to avoid crashing it.\n",
      "To change this limit, set the config variable\n",
      "`--ServerApp.iopub_msg_rate_limit`.\n",
      "\n",
      "Current values:\n",
      "ServerApp.iopub_msg_rate_limit=1000.0 (msgs/sec)\n",
      "ServerApp.rate_limit_window=3.0 (secs)\n",
      "\n",
      "IOPub message rate exceeded.\n",
      "The Jupyter server will temporarily stop sending output\n",
      "to the client in order to avoid crashing it.\n",
      "To change this limit, set the config variable\n",
      "`--ServerApp.iopub_msg_rate_limit`.\n",
      "\n",
      "Current values:\n",
      "ServerApp.iopub_msg_rate_limit=1000.0 (msgs/sec)\n",
      "ServerApp.rate_limit_window=3.0 (secs)\n",
      "\n",
      "IOPub message rate exceeded.\n",
      "The Jupyter server will temporarily stop sending output\n",
      "to the client in order to avoid crashing it.\n",
      "To change this limit, set the config variable\n",
      "`--ServerApp.iopub_msg_rate_limit`.\n",
      "\n",
      "Current values:\n",
      "ServerApp.iopub_msg_rate_limit=1000.0 (msgs/sec)\n",
      "ServerApp.rate_limit_window=3.0 (secs)\n",
      "\n",
      "IOPub message rate exceeded.\n",
      "The Jupyter server will temporarily stop sending output\n",
      "to the client in order to avoid crashing it.\n",
      "To change this limit, set the config variable\n",
      "`--ServerApp.iopub_msg_rate_limit`.\n",
      "\n",
      "Current values:\n",
      "ServerApp.iopub_msg_rate_limit=1000.0 (msgs/sec)\n",
      "ServerApp.rate_limit_window=3.0 (secs)\n",
      "\n",
      "IOPub message rate exceeded.\n",
      "The Jupyter server will temporarily stop sending output\n",
      "to the client in order to avoid crashing it.\n",
      "To change this limit, set the config variable\n",
      "`--ServerApp.iopub_msg_rate_limit`.\n",
      "\n",
      "Current values:\n",
      "ServerApp.iopub_msg_rate_limit=1000.0 (msgs/sec)\n",
      "ServerApp.rate_limit_window=3.0 (secs)\n",
      "\n",
      "IOPub message rate exceeded.\n",
      "The Jupyter server will temporarily stop sending output\n",
      "to the client in order to avoid crashing it.\n",
      "To change this limit, set the config variable\n",
      "`--ServerApp.iopub_msg_rate_limit`.\n",
      "\n",
      "Current values:\n",
      "ServerApp.iopub_msg_rate_limit=1000.0 (msgs/sec)\n",
      "ServerApp.rate_limit_window=3.0 (secs)\n",
      "\n",
      "IOPub message rate exceeded.\n",
      "The Jupyter server will temporarily stop sending output\n",
      "to the client in order to avoid crashing it.\n",
      "To change this limit, set the config variable\n",
      "`--ServerApp.iopub_msg_rate_limit`.\n",
      "\n",
      "Current values:\n",
      "ServerApp.iopub_msg_rate_limit=1000.0 (msgs/sec)\n",
      "ServerApp.rate_limit_window=3.0 (secs)\n",
      "\n",
      "IOPub message rate exceeded.\n",
      "The Jupyter server will temporarily stop sending output\n",
      "to the client in order to avoid crashing it.\n",
      "To change this limit, set the config variable\n",
      "`--ServerApp.iopub_msg_rate_limit`.\n",
      "\n",
      "Current values:\n",
      "ServerApp.iopub_msg_rate_limit=1000.0 (msgs/sec)\n",
      "ServerApp.rate_limit_window=3.0 (secs)\n",
      "\n",
      "IOPub message rate exceeded.\n",
      "The Jupyter server will temporarily stop sending output\n",
      "to the client in order to avoid crashing it.\n",
      "To change this limit, set the config variable\n",
      "`--ServerApp.iopub_msg_rate_limit`.\n",
      "\n",
      "Current values:\n",
      "ServerApp.iopub_msg_rate_limit=1000.0 (msgs/sec)\n",
      "ServerApp.rate_limit_window=3.0 (secs)\n",
      "\n",
      "IOPub message rate exceeded.\n",
      "The Jupyter server will temporarily stop sending output\n",
      "to the client in order to avoid crashing it.\n",
      "To change this limit, set the config variable\n",
      "`--ServerApp.iopub_msg_rate_limit`.\n",
      "\n",
      "Current values:\n",
      "ServerApp.iopub_msg_rate_limit=1000.0 (msgs/sec)\n",
      "ServerApp.rate_limit_window=3.0 (secs)\n",
      "\n",
      "IOPub message rate exceeded.\n",
      "The Jupyter server will temporarily stop sending output\n",
      "to the client in order to avoid crashing it.\n",
      "To change this limit, set the config variable\n",
      "`--ServerApp.iopub_msg_rate_limit`.\n",
      "\n",
      "Current values:\n",
      "ServerApp.iopub_msg_rate_limit=1000.0 (msgs/sec)\n",
      "ServerApp.rate_limit_window=3.0 (secs)\n",
      "\n",
      "IOPub message rate exceeded.\n",
      "The Jupyter server will temporarily stop sending output\n",
      "to the client in order to avoid crashing it.\n",
      "To change this limit, set the config variable\n",
      "`--ServerApp.iopub_msg_rate_limit`.\n",
      "\n",
      "Current values:\n",
      "ServerApp.iopub_msg_rate_limit=1000.0 (msgs/sec)\n",
      "ServerApp.rate_limit_window=3.0 (secs)\n",
      "\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Early stop at epoch 72 / global_step 52272\n"
     ]
    }
   ],
   "execution_count": 23
  },
  {
   "cell_type": "code",
   "source": [
    "record"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-01-25T11:13:04.831967Z",
     "start_time": "2025-01-25T11:13:04.804969Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'train': [{'loss': 6.679615020751953, 'step': 0},\n",
       "  {'loss': 5.598322868347168, 'step': 1},\n",
       "  {'loss': 9.938035011291504, 'step': 2},\n",
       "  {'loss': 6.41159200668335, 'step': 3},\n",
       "  {'loss': 5.476726055145264, 'step': 4},\n",
       "  {'loss': 6.347332000732422, 'step': 5},\n",
       "  {'loss': 6.903439044952393, 'step': 6},\n",
       "  {'loss': 3.4345197677612305, 'step': 7},\n",
       "  {'loss': 7.376781463623047, 'step': 8},\n",
       "  {'loss': 2.617708206176758, 'step': 9},\n",
       "  {'loss': 3.897650718688965, 'step': 10},\n",
       "  {'loss': 3.1506335735321045, 'step': 11},\n",
       "  {'loss': 2.5879855155944824, 'step': 12},\n",
       "  {'loss': 3.4527294635772705, 'step': 13},\n",
       "  {'loss': 3.4290544986724854, 'step': 14},\n",
       "  {'loss': 2.5058510303497314, 'step': 15},\n",
       "  {'loss': 0.9554756879806519, 'step': 16},\n",
       "  {'loss': 2.559145927429199, 'step': 17},\n",
       "  {'loss': 1.7370704412460327, 'step': 18},\n",
       "  {'loss': 3.303535223007202, 'step': 19},\n",
       "  {'loss': 2.9802308082580566, 'step': 20},\n",
       "  {'loss': 1.0826313495635986, 'step': 21},\n",
       "  {'loss': 2.7719461917877197, 'step': 22},\n",
       "  {'loss': 1.9163539409637451, 'step': 23},\n",
       "  {'loss': 1.694753646850586, 'step': 24},\n",
       "  {'loss': 1.4278513193130493, 'step': 25},\n",
       "  {'loss': 0.4290977418422699, 'step': 26},\n",
       "  {'loss': 1.2913792133331299, 'step': 27},\n",
       "  {'loss': 2.2103703022003174, 'step': 28},\n",
       "  {'loss': 0.9430032968521118, 'step': 29},\n",
       "  {'loss': 2.330720901489258, 'step': 30},\n",
       "  {'loss': 1.1865757703781128, 'step': 31},\n",
       "  {'loss': 1.8326858282089233, 'step': 32},\n",
       "  {'loss': 1.1145880222320557, 'step': 33},\n",
       "  {'loss': 1.4838390350341797, 'step': 34},\n",
       "  {'loss': 1.8110965490341187, 'step': 35},\n",
       "  {'loss': 0.7830684185028076, 'step': 36},\n",
       "  {'loss': 0.5346484780311584, 'step': 37},\n",
       "  {'loss': 0.8647193312644958, 'step': 38},\n",
       "  {'loss': 4.508627414703369, 'step': 39},\n",
       "  {'loss': 1.0462018251419067, 'step': 40},\n",
       "  {'loss': 0.9411502480506897, 'step': 41},\n",
       "  {'loss': 0.8751027584075928, 'step': 42},\n",
       "  {'loss': 0.8616491556167603, 'step': 43},\n",
       "  {'loss': 1.1102373600006104, 'step': 44},\n",
       "  {'loss': 0.38029366731643677, 'step': 45},\n",
       "  {'loss': 1.3815377950668335, 'step': 46},\n",
       "  {'loss': 0.3219011723995209, 'step': 47},\n",
       "  {'loss': 1.058278203010559, 'step': 48},\n",
       "  {'loss': 1.4246279001235962, 'step': 49},\n",
       "  {'loss': 0.6309967637062073, 'step': 50},\n",
       "  {'loss': 0.7529904842376709, 'step': 51},\n",
       "  {'loss': 0.8949335217475891, 'step': 52},\n",
       "  {'loss': 0.556949257850647, 'step': 53},\n",
       "  {'loss': 1.4431133270263672, 'step': 54},\n",
       "  {'loss': 0.6586445569992065, 'step': 55},\n",
       "  {'loss': 1.347651720046997, 'step': 56},\n",
       "  {'loss': 0.8739902973175049, 'step': 57},\n",
       "  {'loss': 0.761059582233429, 'step': 58},\n",
       "  {'loss': 1.0035626888275146, 'step': 59},\n",
       "  {'loss': 0.8856554627418518, 'step': 60},\n",
       "  {'loss': 1.005019187927246, 'step': 61},\n",
       "  {'loss': 0.5596216917037964, 'step': 62},\n",
       "  {'loss': 1.551473617553711, 'step': 63},\n",
       "  {'loss': 0.39364075660705566, 'step': 64},\n",
       "  {'loss': 0.5595660209655762, 'step': 65},\n",
       "  {'loss': 0.8129752278327942, 'step': 66},\n",
       "  {'loss': 0.5027738809585571, 'step': 67},\n",
       "  {'loss': 0.9944523572921753, 'step': 68},\n",
       "  {'loss': 1.5413563251495361, 'step': 69},\n",
       "  {'loss': 0.34848591685295105, 'step': 70},\n",
       "  {'loss': 0.5098907947540283, 'step': 71},\n",
       "  {'loss': 0.7396621704101562, 'step': 72},\n",
       "  {'loss': 0.7960605621337891, 'step': 73},\n",
       "  {'loss': 0.712692379951477, 'step': 74},\n",
       "  {'loss': 0.7688322067260742, 'step': 75},\n",
       "  {'loss': 0.6833605766296387, 'step': 76},\n",
       "  {'loss': 0.35451462864875793, 'step': 77},\n",
       "  {'loss': 0.5060604810714722, 'step': 78},\n",
       "  {'loss': 0.45280855894088745, 'step': 79},\n",
       "  {'loss': 0.8669375777244568, 'step': 80},\n",
       "  {'loss': 0.5946692824363708, 'step': 81},\n",
       "  {'loss': 0.6376175284385681, 'step': 82},\n",
       "  {'loss': 0.6180952787399292, 'step': 83},\n",
       "  {'loss': 0.6970077157020569, 'step': 84},\n",
       "  {'loss': 0.8850182890892029, 'step': 85},\n",
       "  {'loss': 0.48993346095085144, 'step': 86},\n",
       "  {'loss': 0.5232675075531006, 'step': 87},\n",
       "  {'loss': 0.9713985919952393, 'step': 88},\n",
       "  {'loss': 0.5459304451942444, 'step': 89},\n",
       "  {'loss': 0.3871864080429077, 'step': 90},\n",
       "  {'loss': 0.49021050333976746, 'step': 91},\n",
       "  {'loss': 0.5147220492362976, 'step': 92},\n",
       "  {'loss': 0.9742302894592285, 'step': 93},\n",
       "  {'loss': 1.3369991779327393, 'step': 94},\n",
       "  {'loss': 0.39478355646133423, 'step': 95},\n",
       "  {'loss': 0.8255646228790283, 'step': 96},\n",
       "  {'loss': 0.5134809017181396, 'step': 97},\n",
       "  {'loss': 0.2513687312602997, 'step': 98},\n",
       "  {'loss': 1.1683709621429443, 'step': 99},\n",
       "  {'loss': 0.29149019718170166, 'step': 100},\n",
       "  {'loss': 0.5708062052726746, 'step': 101},\n",
       "  {'loss': 1.120688557624817, 'step': 102},\n",
       "  {'loss': 0.7564781904220581, 'step': 103},\n",
       "  {'loss': 0.4716678857803345, 'step': 104},\n",
       "  {'loss': 0.8717474937438965, 'step': 105},\n",
       "  {'loss': 0.5061691403388977, 'step': 106},\n",
       "  {'loss': 0.846473217010498, 'step': 107},\n",
       "  {'loss': 0.7288489937782288, 'step': 108},\n",
       "  {'loss': 0.49267515540122986, 'step': 109},\n",
       "  {'loss': 0.993026614189148, 'step': 110},\n",
       "  {'loss': 0.3834320604801178, 'step': 111},\n",
       "  {'loss': 0.6855810880661011, 'step': 112},\n",
       "  {'loss': 0.5045652985572815, 'step': 113},\n",
       "  {'loss': 1.356459617614746, 'step': 114},\n",
       "  {'loss': 0.3813703656196594, 'step': 115},\n",
       "  {'loss': 0.637582004070282, 'step': 116},\n",
       "  {'loss': 0.5479675531387329, 'step': 117},\n",
       "  {'loss': 0.6112518310546875, 'step': 118},\n",
       "  {'loss': 0.38098573684692383, 'step': 119},\n",
       "  {'loss': 0.7004761099815369, 'step': 120},\n",
       "  {'loss': 1.3995931148529053, 'step': 121},\n",
       "  {'loss': 1.026910662651062, 'step': 122},\n",
       "  {'loss': 0.895787239074707, 'step': 123},\n",
       "  {'loss': 0.39978593587875366, 'step': 124},\n",
       "  {'loss': 0.5689029693603516, 'step': 125},\n",
       "  {'loss': 0.6172510385513306, 'step': 126},\n",
       "  {'loss': 0.19924841821193695, 'step': 127},\n",
       "  {'loss': 0.7570476531982422, 'step': 128},\n",
       "  {'loss': 0.5889453291893005, 'step': 129},\n",
       "  {'loss': 0.5028848648071289, 'step': 130},\n",
       "  {'loss': 0.6236550807952881, 'step': 131},\n",
       "  {'loss': 0.5832330584526062, 'step': 132},\n",
       "  {'loss': 0.3855590224266052, 'step': 133},\n",
       "  {'loss': 0.9826047420501709, 'step': 134},\n",
       "  {'loss': 0.7631332278251648, 'step': 135},\n",
       "  {'loss': 0.4014054536819458, 'step': 136},\n",
       "  {'loss': 0.4397045969963074, 'step': 137},\n",
       "  {'loss': 0.8081876039505005, 'step': 138},\n",
       "  {'loss': 0.9998729228973389, 'step': 139},\n",
       "  {'loss': 0.14227570593357086, 'step': 140},\n",
       "  {'loss': 0.3176090121269226, 'step': 141},\n",
       "  {'loss': 0.6880437135696411, 'step': 142},\n",
       "  {'loss': 0.254226416349411, 'step': 143},\n",
       "  {'loss': 1.001124382019043, 'step': 144},\n",
       "  {'loss': 0.39717763662338257, 'step': 145},\n",
       "  {'loss': 0.6787531971931458, 'step': 146},\n",
       "  {'loss': 0.21671931445598602, 'step': 147},\n",
       "  {'loss': 1.19992196559906, 'step': 148},\n",
       "  {'loss': 0.7010836005210876, 'step': 149},\n",
       "  {'loss': 0.6995960474014282, 'step': 150},\n",
       "  {'loss': 0.3796057403087616, 'step': 151},\n",
       "  {'loss': 0.7424487471580505, 'step': 152},\n",
       "  {'loss': 0.6381096839904785, 'step': 153},\n",
       "  {'loss': 0.6725766658782959, 'step': 154},\n",
       "  {'loss': 1.7136034965515137, 'step': 155},\n",
       "  {'loss': 0.8394454717636108, 'step': 156},\n",
       "  {'loss': 0.5180951356887817, 'step': 157},\n",
       "  {'loss': 0.21900947391986847, 'step': 158},\n",
       "  {'loss': 0.5847679376602173, 'step': 159},\n",
       "  {'loss': 0.6872661113739014, 'step': 160},\n",
       "  {'loss': 0.42132899165153503, 'step': 161},\n",
       "  {'loss': 0.593518853187561, 'step': 162},\n",
       "  {'loss': 0.5098644495010376, 'step': 163},\n",
       "  {'loss': 0.7009608745574951, 'step': 164},\n",
       "  {'loss': 0.6069410443305969, 'step': 165},\n",
       "  {'loss': 1.3394827842712402, 'step': 166},\n",
       "  {'loss': 0.5448811650276184, 'step': 167},\n",
       "  {'loss': 1.2665246725082397, 'step': 168},\n",
       "  {'loss': 0.9141704440116882, 'step': 169},\n",
       "  {'loss': 0.3051314353942871, 'step': 170},\n",
       "  {'loss': 0.5378551483154297, 'step': 171},\n",
       "  {'loss': 3.424499034881592, 'step': 172},\n",
       "  {'loss': 1.5926321744918823, 'step': 173},\n",
       "  {'loss': 0.7487571239471436, 'step': 174},\n",
       "  {'loss': 1.1628265380859375, 'step': 175},\n",
       "  {'loss': 0.40177586674690247, 'step': 176},\n",
       "  {'loss': 1.2100393772125244, 'step': 177},\n",
       "  {'loss': 0.5320925712585449, 'step': 178},\n",
       "  {'loss': 1.6136655807495117, 'step': 179},\n",
       "  {'loss': 0.7815264463424683, 'step': 180},\n",
       "  {'loss': 0.28212571144104004, 'step': 181},\n",
       "  {'loss': 0.7664120197296143, 'step': 182},\n",
       "  {'loss': 0.8541122674942017, 'step': 183},\n",
       "  {'loss': 0.3525029122829437, 'step': 184},\n",
       "  {'loss': 0.3766835629940033, 'step': 185},\n",
       "  {'loss': 0.47165369987487793, 'step': 186},\n",
       "  {'loss': 1.1584120988845825, 'step': 187},\n",
       "  {'loss': 0.3543641269207001, 'step': 188},\n",
       "  {'loss': 1.0834252834320068, 'step': 189},\n",
       "  {'loss': 0.5572212934494019, 'step': 190},\n",
       "  {'loss': 0.41081878542900085, 'step': 191},\n",
       "  {'loss': 0.19836921989917755, 'step': 192},\n",
       "  {'loss': 0.5612936019897461, 'step': 193},\n",
       "  {'loss': 0.36530041694641113, 'step': 194},\n",
       "  {'loss': 0.2722889482975006, 'step': 195},\n",
       "  {'loss': 0.4205140769481659, 'step': 196},\n",
       "  {'loss': 0.45937442779541016, 'step': 197},\n",
       "  {'loss': 0.47950631380081177, 'step': 198},\n",
       "  {'loss': 0.5253921747207642, 'step': 199},\n",
       "  {'loss': 0.4043009281158447, 'step': 200},\n",
       "  {'loss': 0.5277431011199951, 'step': 201},\n",
       "  {'loss': 0.9771412014961243, 'step': 202},\n",
       "  {'loss': 0.24786941707134247, 'step': 203},\n",
       "  {'loss': 0.771160364151001, 'step': 204},\n",
       "  {'loss': 0.7651270627975464, 'step': 205},\n",
       "  {'loss': 0.6095435619354248, 'step': 206},\n",
       "  {'loss': 1.016587257385254, 'step': 207},\n",
       "  {'loss': 1.0289695262908936, 'step': 208},\n",
       "  {'loss': 0.7942851185798645, 'step': 209},\n",
       "  {'loss': 0.24664895236492157, 'step': 210},\n",
       "  {'loss': 0.42553359270095825, 'step': 211},\n",
       "  {'loss': 0.557695746421814, 'step': 212},\n",
       "  {'loss': 0.9939018487930298, 'step': 213},\n",
       "  {'loss': 0.8162933588027954, 'step': 214},\n",
       "  {'loss': 1.3388621807098389, 'step': 215},\n",
       "  {'loss': 0.24215306341648102, 'step': 216},\n",
       "  {'loss': 0.45956364274024963, 'step': 217},\n",
       "  {'loss': 0.5085759162902832, 'step': 218},\n",
       "  {'loss': 0.49859619140625, 'step': 219},\n",
       "  {'loss': 0.2011793851852417, 'step': 220},\n",
       "  {'loss': 0.30497458577156067, 'step': 221},\n",
       "  {'loss': 0.4142959713935852, 'step': 222},\n",
       "  {'loss': 0.37982574105262756, 'step': 223},\n",
       "  {'loss': 0.9939384460449219, 'step': 224},\n",
       "  {'loss': 0.7887073159217834, 'step': 225},\n",
       "  {'loss': 0.48620083928108215, 'step': 226},\n",
       "  {'loss': 0.30302074551582336, 'step': 227},\n",
       "  {'loss': 0.5636239051818848, 'step': 228},\n",
       "  {'loss': 0.3985792398452759, 'step': 229},\n",
       "  {'loss': 0.3246392011642456, 'step': 230},\n",
       "  {'loss': 0.5491281151771545, 'step': 231},\n",
       "  {'loss': 0.5597913265228271, 'step': 232},\n",
       "  {'loss': 0.3502748906612396, 'step': 233},\n",
       "  {'loss': 0.41766995191574097, 'step': 234},\n",
       "  {'loss': 0.2852265238761902, 'step': 235},\n",
       "  {'loss': 0.4446636736392975, 'step': 236},\n",
       "  {'loss': 0.6431004405021667, 'step': 237},\n",
       "  {'loss': 0.6120253801345825, 'step': 238},\n",
       "  {'loss': 0.42721331119537354, 'step': 239},\n",
       "  {'loss': 2.2352523803710938, 'step': 240},\n",
       "  {'loss': 0.553371250629425, 'step': 241},\n",
       "  {'loss': 0.3474930226802826, 'step': 242},\n",
       "  {'loss': 0.36578625440597534, 'step': 243},\n",
       "  {'loss': 0.18858219683170319, 'step': 244},\n",
       "  {'loss': 0.46079614758491516, 'step': 245},\n",
       "  {'loss': 0.6506214141845703, 'step': 246},\n",
       "  {'loss': 0.38135483860969543, 'step': 247},\n",
       "  {'loss': 0.35403338074684143, 'step': 248},\n",
       "  {'loss': 0.7777129411697388, 'step': 249},\n",
       "  {'loss': 1.6493936777114868, 'step': 250},\n",
       "  {'loss': 0.3301214873790741, 'step': 251},\n",
       "  {'loss': 0.4871409237384796, 'step': 252},\n",
       "  {'loss': 0.5919261574745178, 'step': 253},\n",
       "  {'loss': 0.31948256492614746, 'step': 254},\n",
       "  {'loss': 0.4183069169521332, 'step': 255},\n",
       "  {'loss': 0.40243858098983765, 'step': 256},\n",
       "  {'loss': 1.5436475276947021, 'step': 257},\n",
       "  {'loss': 0.8383263349533081, 'step': 258},\n",
       "  {'loss': 0.2596416771411896, 'step': 259},\n",
       "  {'loss': 1.489084243774414, 'step': 260},\n",
       "  {'loss': 0.6756028532981873, 'step': 261},\n",
       "  {'loss': 0.2901081144809723, 'step': 262},\n",
       "  {'loss': 0.26314112544059753, 'step': 263},\n",
       "  {'loss': 0.6266317367553711, 'step': 264},\n",
       "  {'loss': 0.2569034993648529, 'step': 265},\n",
       "  {'loss': 1.0515074729919434, 'step': 266},\n",
       "  {'loss': 0.7900248765945435, 'step': 267},\n",
       "  {'loss': 0.3412051796913147, 'step': 268},\n",
       "  {'loss': 0.5540246963500977, 'step': 269},\n",
       "  {'loss': 0.1986745297908783, 'step': 270},\n",
       "  {'loss': 0.6580144762992859, 'step': 271},\n",
       "  {'loss': 0.6877096891403198, 'step': 272},\n",
       "  {'loss': 0.9940342903137207, 'step': 273},\n",
       "  {'loss': 0.5482449531555176, 'step': 274},\n",
       "  {'loss': 1.2619566917419434, 'step': 275},\n",
       "  {'loss': 0.382534384727478, 'step': 276},\n",
       "  {'loss': 0.27130651473999023, 'step': 277},\n",
       "  {'loss': 0.8801281452178955, 'step': 278},\n",
       "  {'loss': 0.39774176478385925, 'step': 279},\n",
       "  {'loss': 0.47808462381362915, 'step': 280},\n",
       "  {'loss': 0.33627480268478394, 'step': 281},\n",
       "  {'loss': 0.3699962794780731, 'step': 282},\n",
       "  {'loss': 0.4376087486743927, 'step': 283},\n",
       "  {'loss': 1.1966571807861328, 'step': 284},\n",
       "  {'loss': 2.0349483489990234, 'step': 285},\n",
       "  {'loss': 0.3484214246273041, 'step': 286},\n",
       "  {'loss': 0.6026021242141724, 'step': 287},\n",
       "  {'loss': 1.0160911083221436, 'step': 288},\n",
       "  {'loss': 0.844998300075531, 'step': 289},\n",
       "  {'loss': 0.7268382906913757, 'step': 290},\n",
       "  {'loss': 0.589097261428833, 'step': 291},\n",
       "  {'loss': 1.053098440170288, 'step': 292},\n",
       "  {'loss': 1.0907180309295654, 'step': 293},\n",
       "  {'loss': 0.944661557674408, 'step': 294},\n",
       "  {'loss': 0.31910455226898193, 'step': 295},\n",
       "  {'loss': 0.30581918358802795, 'step': 296},\n",
       "  {'loss': 0.3486860990524292, 'step': 297},\n",
       "  {'loss': 0.777446448802948, 'step': 298},\n",
       "  {'loss': 0.34708648920059204, 'step': 299},\n",
       "  {'loss': 0.29927369952201843, 'step': 300},\n",
       "  {'loss': 0.527432918548584, 'step': 301},\n",
       "  {'loss': 0.373071551322937, 'step': 302},\n",
       "  {'loss': 0.5686107277870178, 'step': 303},\n",
       "  {'loss': 0.19741518795490265, 'step': 304},\n",
       "  {'loss': 0.586892306804657, 'step': 305},\n",
       "  {'loss': 0.3024085462093353, 'step': 306},\n",
       "  {'loss': 0.4741438031196594, 'step': 307},\n",
       "  {'loss': 0.4377354383468628, 'step': 308},\n",
       "  {'loss': 1.5828988552093506, 'step': 309},\n",
       "  {'loss': 0.5676754713058472, 'step': 310},\n",
       "  {'loss': 0.49976056814193726, 'step': 311},\n",
       "  {'loss': 1.3683550357818604, 'step': 312},\n",
       "  {'loss': 0.418927937746048, 'step': 313},\n",
       "  {'loss': 0.3137056231498718, 'step': 314},\n",
       "  {'loss': 0.6407710313796997, 'step': 315},\n",
       "  {'loss': 1.2321395874023438, 'step': 316},\n",
       "  {'loss': 0.3575904071331024, 'step': 317},\n",
       "  {'loss': 0.6100547909736633, 'step': 318},\n",
       "  {'loss': 0.19906026124954224, 'step': 319},\n",
       "  {'loss': 0.28523167967796326, 'step': 320},\n",
       "  {'loss': 0.4690842628479004, 'step': 321},\n",
       "  {'loss': 0.523076593875885, 'step': 322},\n",
       "  {'loss': 0.4869469702243805, 'step': 323},\n",
       "  {'loss': 0.36601507663726807, 'step': 324},\n",
       "  {'loss': 0.48690247535705566, 'step': 325},\n",
       "  {'loss': 0.5978207588195801, 'step': 326},\n",
       "  {'loss': 0.36435994505882263, 'step': 327},\n",
       "  {'loss': 0.6653162240982056, 'step': 328},\n",
       "  {'loss': 0.5273163914680481, 'step': 329},\n",
       "  {'loss': 0.575275182723999, 'step': 330},\n",
       "  {'loss': 0.7230175733566284, 'step': 331},\n",
       "  {'loss': 0.8051405549049377, 'step': 332},\n",
       "  {'loss': 0.44871699810028076, 'step': 333},\n",
       "  {'loss': 0.7432352900505066, 'step': 334},\n",
       "  {'loss': 0.4026145339012146, 'step': 335},\n",
       "  {'loss': 0.334541380405426, 'step': 336},\n",
       "  {'loss': 0.4133375287055969, 'step': 337},\n",
       "  {'loss': 0.36780160665512085, 'step': 338},\n",
       "  {'loss': 0.3295196294784546, 'step': 339},\n",
       "  {'loss': 0.23366370797157288, 'step': 340},\n",
       "  {'loss': 0.6488495469093323, 'step': 341},\n",
       "  {'loss': 0.4677140712738037, 'step': 342},\n",
       "  {'loss': 0.2880052328109741, 'step': 343},\n",
       "  {'loss': 0.18408621847629547, 'step': 344},\n",
       "  {'loss': 1.0270016193389893, 'step': 345},\n",
       "  {'loss': 0.6715859770774841, 'step': 346},\n",
       "  {'loss': 0.5889579057693481, 'step': 347},\n",
       "  {'loss': 0.4010124206542969, 'step': 348},\n",
       "  {'loss': 0.7553746104240417, 'step': 349},\n",
       "  {'loss': 0.26268187165260315, 'step': 350},\n",
       "  {'loss': 0.303562730550766, 'step': 351},\n",
       "  {'loss': 0.4509274363517761, 'step': 352},\n",
       "  {'loss': 0.40305575728416443, 'step': 353},\n",
       "  {'loss': 0.3868926167488098, 'step': 354},\n",
       "  {'loss': 0.5600966811180115, 'step': 355},\n",
       "  {'loss': 0.8921113610267639, 'step': 356},\n",
       "  {'loss': 1.231259822845459, 'step': 357},\n",
       "  {'loss': 0.32151681184768677, 'step': 358},\n",
       "  {'loss': 0.7931877970695496, 'step': 359},\n",
       "  {'loss': 1.1365675926208496, 'step': 360},\n",
       "  {'loss': 0.4051782488822937, 'step': 361},\n",
       "  {'loss': 0.49937087297439575, 'step': 362},\n",
       "  {'loss': 0.9730100631713867, 'step': 363},\n",
       "  {'loss': 0.2068076878786087, 'step': 364},\n",
       "  {'loss': 0.8899092078208923, 'step': 365},\n",
       "  {'loss': 0.2651354670524597, 'step': 366},\n",
       "  {'loss': 0.6641783714294434, 'step': 367},\n",
       "  {'loss': 1.7059024572372437, 'step': 368},\n",
       "  {'loss': 1.2698941230773926, 'step': 369},\n",
       "  {'loss': 0.18380942940711975, 'step': 370},\n",
       "  {'loss': 0.3771698474884033, 'step': 371},\n",
       "  {'loss': 1.2116881608963013, 'step': 372},\n",
       "  {'loss': 0.23705214262008667, 'step': 373},\n",
       "  {'loss': 0.25532740354537964, 'step': 374},\n",
       "  {'loss': 1.2217952013015747, 'step': 375},\n",
       "  {'loss': 0.26425275206565857, 'step': 376},\n",
       "  {'loss': 0.8506281971931458, 'step': 377},\n",
       "  {'loss': 0.5759018659591675, 'step': 378},\n",
       "  {'loss': 0.9017003774642944, 'step': 379},\n",
       "  {'loss': 0.5870772004127502, 'step': 380},\n",
       "  {'loss': 0.3477409780025482, 'step': 381},\n",
       "  {'loss': 0.502067506313324, 'step': 382},\n",
       "  {'loss': 0.6619340181350708, 'step': 383},\n",
       "  {'loss': 0.2596474289894104, 'step': 384},\n",
       "  {'loss': 0.6321285963058472, 'step': 385},\n",
       "  {'loss': 0.23548774421215057, 'step': 386},\n",
       "  {'loss': 0.23894649744033813, 'step': 387},\n",
       "  {'loss': 0.22023886442184448, 'step': 388},\n",
       "  {'loss': 0.4666316509246826, 'step': 389},\n",
       "  {'loss': 0.5911759734153748, 'step': 390},\n",
       "  {'loss': 0.1874779909849167, 'step': 391},\n",
       "  {'loss': 0.4509822130203247, 'step': 392},\n",
       "  {'loss': 0.7090898156166077, 'step': 393},\n",
       "  {'loss': 0.5701989531517029, 'step': 394},\n",
       "  {'loss': 0.6189585328102112, 'step': 395},\n",
       "  {'loss': 0.6171106100082397, 'step': 396},\n",
       "  {'loss': 0.3558312654495239, 'step': 397},\n",
       "  {'loss': 0.3264460861682892, 'step': 398},\n",
       "  {'loss': 0.37123146653175354, 'step': 399},\n",
       "  {'loss': 0.3300996422767639, 'step': 400},\n",
       "  {'loss': 0.17880579829216003, 'step': 401},\n",
       "  {'loss': 0.2489245980978012, 'step': 402},\n",
       "  {'loss': 0.7117863893508911, 'step': 403},\n",
       "  {'loss': 0.45825207233428955, 'step': 404},\n",
       "  {'loss': 0.26327115297317505, 'step': 405},\n",
       "  {'loss': 0.34745052456855774, 'step': 406},\n",
       "  {'loss': 0.4081895053386688, 'step': 407},\n",
       "  {'loss': 0.9754041433334351, 'step': 408},\n",
       "  {'loss': 0.3097572326660156, 'step': 409},\n",
       "  {'loss': 0.9205092191696167, 'step': 410},\n",
       "  {'loss': 0.632953941822052, 'step': 411},\n",
       "  {'loss': 0.5407505035400391, 'step': 412},\n",
       "  {'loss': 0.2894328534603119, 'step': 413},\n",
       "  {'loss': 0.6175462007522583, 'step': 414},\n",
       "  {'loss': 0.554629385471344, 'step': 415},\n",
       "  {'loss': 0.25248727202415466, 'step': 416},\n",
       "  {'loss': 0.3312026560306549, 'step': 417},\n",
       "  {'loss': 0.35320261120796204, 'step': 418},\n",
       "  {'loss': 0.6680544018745422, 'step': 419},\n",
       "  {'loss': 0.23892833292484283, 'step': 420},\n",
       "  {'loss': 0.9311739802360535, 'step': 421},\n",
       "  {'loss': 1.1443251371383667, 'step': 422},\n",
       "  {'loss': 0.7216336727142334, 'step': 423},\n",
       "  {'loss': 0.3574522137641907, 'step': 424},\n",
       "  {'loss': 0.4415130615234375, 'step': 425},\n",
       "  {'loss': 0.47699934244155884, 'step': 426},\n",
       "  {'loss': 0.2914201617240906, 'step': 427},\n",
       "  {'loss': 0.6200674772262573, 'step': 428},\n",
       "  {'loss': 0.6103039383888245, 'step': 429},\n",
       "  {'loss': 0.567942202091217, 'step': 430},\n",
       "  {'loss': 0.7088431715965271, 'step': 431},\n",
       "  {'loss': 0.3256648778915405, 'step': 432},\n",
       "  {'loss': 0.5005056858062744, 'step': 433},\n",
       "  {'loss': 0.43099862337112427, 'step': 434},\n",
       "  {'loss': 0.3714495599269867, 'step': 435},\n",
       "  {'loss': 0.33320480585098267, 'step': 436},\n",
       "  {'loss': 0.22021447122097015, 'step': 437},\n",
       "  {'loss': 0.44598859548568726, 'step': 438},\n",
       "  {'loss': 0.5784626603126526, 'step': 439},\n",
       "  {'loss': 1.2269757986068726, 'step': 440},\n",
       "  {'loss': 1.1776537895202637, 'step': 441},\n",
       "  {'loss': 1.6964199542999268, 'step': 442},\n",
       "  {'loss': 0.8962727189064026, 'step': 443},\n",
       "  {'loss': 0.9394087791442871, 'step': 444},\n",
       "  {'loss': 0.6673988103866577, 'step': 445},\n",
       "  {'loss': 0.7994341254234314, 'step': 446},\n",
       "  {'loss': 0.4667432904243469, 'step': 447},\n",
       "  {'loss': 0.7161127924919128, 'step': 448},\n",
       "  {'loss': 0.3353530764579773, 'step': 449},\n",
       "  {'loss': 0.6371873617172241, 'step': 450},\n",
       "  {'loss': 0.6850342750549316, 'step': 451},\n",
       "  {'loss': 0.6160441637039185, 'step': 452},\n",
       "  {'loss': 0.31229227781295776, 'step': 453},\n",
       "  {'loss': 0.9649307727813721, 'step': 454},\n",
       "  {'loss': 0.292596697807312, 'step': 455},\n",
       "  {'loss': 0.24634909629821777, 'step': 456},\n",
       "  {'loss': 0.5741479992866516, 'step': 457},\n",
       "  {'loss': 0.8279140591621399, 'step': 458},\n",
       "  {'loss': 0.37439635396003723, 'step': 459},\n",
       "  {'loss': 0.41082271933555603, 'step': 460},\n",
       "  {'loss': 0.4032605290412903, 'step': 461},\n",
       "  {'loss': 0.192651629447937, 'step': 462},\n",
       "  {'loss': 0.5745517015457153, 'step': 463},\n",
       "  {'loss': 0.39812347292900085, 'step': 464},\n",
       "  {'loss': 0.4592413902282715, 'step': 465},\n",
       "  {'loss': 0.10618463903665543, 'step': 466},\n",
       "  {'loss': 0.42291006445884705, 'step': 467},\n",
       "  {'loss': 0.9808692336082458, 'step': 468},\n",
       "  {'loss': 0.7593663930892944, 'step': 469},\n",
       "  {'loss': 0.7511577606201172, 'step': 470},\n",
       "  {'loss': 0.452292799949646, 'step': 471},\n",
       "  {'loss': 0.5251697301864624, 'step': 472},\n",
       "  {'loss': 0.20666992664337158, 'step': 473},\n",
       "  {'loss': 0.3153771162033081, 'step': 474},\n",
       "  {'loss': 0.39059239625930786, 'step': 475},\n",
       "  {'loss': 0.4353543221950531, 'step': 476},\n",
       "  {'loss': 0.8276959657669067, 'step': 477},\n",
       "  {'loss': 0.9566572904586792, 'step': 478},\n",
       "  {'loss': 0.5041590929031372, 'step': 479},\n",
       "  {'loss': 0.8169320225715637, 'step': 480},\n",
       "  {'loss': 0.9653395414352417, 'step': 481},\n",
       "  {'loss': 1.7398085594177246, 'step': 482},\n",
       "  {'loss': 0.2977391481399536, 'step': 483},\n",
       "  {'loss': 0.23209494352340698, 'step': 484},\n",
       "  {'loss': 0.4730580747127533, 'step': 485},\n",
       "  {'loss': 0.22063706815242767, 'step': 486},\n",
       "  {'loss': 0.6067927479743958, 'step': 487},\n",
       "  {'loss': 0.37411731481552124, 'step': 488},\n",
       "  {'loss': 0.22631698846817017, 'step': 489},\n",
       "  {'loss': 0.807547390460968, 'step': 490},\n",
       "  {'loss': 0.8463812470436096, 'step': 491},\n",
       "  {'loss': 0.17903479933738708, 'step': 492},\n",
       "  {'loss': 0.494506299495697, 'step': 493},\n",
       "  {'loss': 0.24241386353969574, 'step': 494},\n",
       "  {'loss': 0.7684889435768127, 'step': 495},\n",
       "  {'loss': 0.9036463499069214, 'step': 496},\n",
       "  {'loss': 0.5790637731552124, 'step': 497},\n",
       "  {'loss': 0.4168001413345337, 'step': 498},\n",
       "  {'loss': 0.5703797936439514, 'step': 499},\n",
       "  {'loss': 1.5827102661132812, 'step': 500},\n",
       "  {'loss': 0.39577239751815796, 'step': 501},\n",
       "  {'loss': 0.5105273723602295, 'step': 502},\n",
       "  {'loss': 0.4389933943748474, 'step': 503},\n",
       "  {'loss': 0.27514708042144775, 'step': 504},\n",
       "  {'loss': 0.3474639058113098, 'step': 505},\n",
       "  {'loss': 0.3312217891216278, 'step': 506},\n",
       "  {'loss': 0.14120398461818695, 'step': 507},\n",
       "  {'loss': 0.4128026068210602, 'step': 508},\n",
       "  {'loss': 0.2682037949562073, 'step': 509},\n",
       "  {'loss': 0.28648197650909424, 'step': 510},\n",
       "  {'loss': 0.8249033093452454, 'step': 511},\n",
       "  {'loss': 0.20401395857334137, 'step': 512},\n",
       "  {'loss': 0.10197187960147858, 'step': 513},\n",
       "  {'loss': 0.7555931806564331, 'step': 514},\n",
       "  {'loss': 0.3369360864162445, 'step': 515},\n",
       "  {'loss': 0.8494923710823059, 'step': 516},\n",
       "  {'loss': 0.5581581592559814, 'step': 517},\n",
       "  {'loss': 0.43168410658836365, 'step': 518},\n",
       "  {'loss': 0.242084339261055, 'step': 519},\n",
       "  {'loss': 0.8321186304092407, 'step': 520},\n",
       "  {'loss': 1.3357622623443604, 'step': 521},\n",
       "  {'loss': 0.24857361614704132, 'step': 522},\n",
       "  {'loss': 0.4928295910358429, 'step': 523},\n",
       "  {'loss': 0.33508995175361633, 'step': 524},\n",
       "  {'loss': 0.31714314222335815, 'step': 525},\n",
       "  {'loss': 0.8071945905685425, 'step': 526},\n",
       "  {'loss': 0.5491775274276733, 'step': 527},\n",
       "  {'loss': 0.44359511137008667, 'step': 528},\n",
       "  {'loss': 0.3068762421607971, 'step': 529},\n",
       "  {'loss': 0.2638685405254364, 'step': 530},\n",
       "  {'loss': 0.29750141501426697, 'step': 531},\n",
       "  {'loss': 0.41763395071029663, 'step': 532},\n",
       "  {'loss': 0.600236713886261, 'step': 533},\n",
       "  {'loss': 0.2355482429265976, 'step': 534},\n",
       "  {'loss': 0.21635064482688904, 'step': 535},\n",
       "  {'loss': 0.4759591817855835, 'step': 536},\n",
       "  {'loss': 0.6348117589950562, 'step': 537},\n",
       "  {'loss': 0.3063333332538605, 'step': 538},\n",
       "  {'loss': 0.5051950216293335, 'step': 539},\n",
       "  {'loss': 0.38192906975746155, 'step': 540},\n",
       "  {'loss': 0.7185096740722656, 'step': 541},\n",
       "  {'loss': 0.23916137218475342, 'step': 542},\n",
       "  {'loss': 0.26272037625312805, 'step': 543},\n",
       "  {'loss': 0.1806584596633911, 'step': 544},\n",
       "  {'loss': 0.6130309104919434, 'step': 545},\n",
       "  {'loss': 0.3541666567325592, 'step': 546},\n",
       "  {'loss': 0.6183360815048218, 'step': 547},\n",
       "  {'loss': 0.5870795845985413, 'step': 548},\n",
       "  {'loss': 0.28941696882247925, 'step': 549},\n",
       "  {'loss': 0.7478727698326111, 'step': 550},\n",
       "  {'loss': 0.39626872539520264, 'step': 551},\n",
       "  {'loss': 0.24499690532684326, 'step': 552},\n",
       "  {'loss': 0.5393679738044739, 'step': 553},\n",
       "  {'loss': 0.2803824543952942, 'step': 554},\n",
       "  {'loss': 0.841042160987854, 'step': 555},\n",
       "  {'loss': 0.1700943261384964, 'step': 556},\n",
       "  {'loss': 0.9562292098999023, 'step': 557},\n",
       "  {'loss': 0.4957367777824402, 'step': 558},\n",
       "  {'loss': 0.9295334815979004, 'step': 559},\n",
       "  {'loss': 0.43772006034851074, 'step': 560},\n",
       "  {'loss': 0.4018319249153137, 'step': 561},\n",
       "  {'loss': 0.639281153678894, 'step': 562},\n",
       "  {'loss': 0.46657106280326843, 'step': 563},\n",
       "  {'loss': 0.29535335302352905, 'step': 564},\n",
       "  {'loss': 0.6740114688873291, 'step': 565},\n",
       "  {'loss': 0.4449496567249298, 'step': 566},\n",
       "  {'loss': 0.17870965600013733, 'step': 567},\n",
       "  {'loss': 0.25811123847961426, 'step': 568},\n",
       "  {'loss': 0.32262590527534485, 'step': 569},\n",
       "  {'loss': 0.40056729316711426, 'step': 570},\n",
       "  {'loss': 0.28373420238494873, 'step': 571},\n",
       "  {'loss': 0.32835352420806885, 'step': 572},\n",
       "  {'loss': 0.46780550479888916, 'step': 573},\n",
       "  {'loss': 0.9560285806655884, 'step': 574},\n",
       "  {'loss': 0.20727181434631348, 'step': 575},\n",
       "  {'loss': 0.7231907844543457, 'step': 576},\n",
       "  {'loss': 0.6987773180007935, 'step': 577},\n",
       "  {'loss': 0.25879281759262085, 'step': 578},\n",
       "  {'loss': 0.7403464913368225, 'step': 579},\n",
       "  {'loss': 0.37120333313941956, 'step': 580},\n",
       "  {'loss': 0.23860220611095428, 'step': 581},\n",
       "  {'loss': 0.14913520216941833, 'step': 582},\n",
       "  {'loss': 0.30967724323272705, 'step': 583},\n",
       "  {'loss': 0.40585166215896606, 'step': 584},\n",
       "  {'loss': 0.2667875587940216, 'step': 585},\n",
       "  {'loss': 0.32475560903549194, 'step': 586},\n",
       "  {'loss': 0.5030517578125, 'step': 587},\n",
       "  {'loss': 0.47271567583084106, 'step': 588},\n",
       "  {'loss': 0.194257915019989, 'step': 589},\n",
       "  {'loss': 0.33184897899627686, 'step': 590},\n",
       "  {'loss': 0.27029940485954285, 'step': 591},\n",
       "  {'loss': 0.19706504046916962, 'step': 592},\n",
       "  {'loss': 0.1724628210067749, 'step': 593},\n",
       "  {'loss': 0.3175499439239502, 'step': 594},\n",
       "  {'loss': 0.4881674647331238, 'step': 595},\n",
       "  {'loss': 0.47683480381965637, 'step': 596},\n",
       "  {'loss': 0.3280471861362457, 'step': 597},\n",
       "  {'loss': 0.546373188495636, 'step': 598},\n",
       "  {'loss': 0.38705772161483765, 'step': 599},\n",
       "  {'loss': 0.36041903495788574, 'step': 600},\n",
       "  {'loss': 0.4477526843547821, 'step': 601},\n",
       "  {'loss': 0.1823633909225464, 'step': 602},\n",
       "  {'loss': 0.9123204350471497, 'step': 603},\n",
       "  {'loss': 0.2971341609954834, 'step': 604},\n",
       "  {'loss': 1.210376262664795, 'step': 605},\n",
       "  {'loss': 0.2162206470966339, 'step': 606},\n",
       "  {'loss': 0.3735283613204956, 'step': 607},\n",
       "  {'loss': 0.5902178883552551, 'step': 608},\n",
       "  {'loss': 0.39372631907463074, 'step': 609},\n",
       "  {'loss': 0.4327062666416168, 'step': 610},\n",
       "  {'loss': 0.46668872237205505, 'step': 611},\n",
       "  {'loss': 0.6390325427055359, 'step': 612},\n",
       "  {'loss': 0.28643783926963806, 'step': 613},\n",
       "  {'loss': 0.29224255681037903, 'step': 614},\n",
       "  {'loss': 0.21995121240615845, 'step': 615},\n",
       "  {'loss': 0.16258926689624786, 'step': 616},\n",
       "  {'loss': 0.23197253048419952, 'step': 617},\n",
       "  {'loss': 0.20241789519786835, 'step': 618},\n",
       "  {'loss': 0.3195841610431671, 'step': 619},\n",
       "  {'loss': 0.5434730648994446, 'step': 620},\n",
       "  {'loss': 0.5469030141830444, 'step': 621},\n",
       "  {'loss': 0.6302102208137512, 'step': 622},\n",
       "  {'loss': 0.6284889578819275, 'step': 623},\n",
       "  {'loss': 0.7689507603645325, 'step': 624},\n",
       "  {'loss': 0.30699846148490906, 'step': 625},\n",
       "  {'loss': 0.5516417026519775, 'step': 626},\n",
       "  {'loss': 0.2511019706726074, 'step': 627},\n",
       "  {'loss': 0.20566405355930328, 'step': 628},\n",
       "  {'loss': 0.2763100564479828, 'step': 629},\n",
       "  {'loss': 0.3266541063785553, 'step': 630},\n",
       "  {'loss': 0.36758285760879517, 'step': 631},\n",
       "  {'loss': 0.8258633613586426, 'step': 632},\n",
       "  {'loss': 0.4428233802318573, 'step': 633},\n",
       "  {'loss': 0.18733122944831848, 'step': 634},\n",
       "  {'loss': 0.34589385986328125, 'step': 635},\n",
       "  {'loss': 0.7670795917510986, 'step': 636},\n",
       "  {'loss': 0.26084595918655396, 'step': 637},\n",
       "  {'loss': 0.17892631888389587, 'step': 638},\n",
       "  {'loss': 0.17755062878131866, 'step': 639},\n",
       "  {'loss': 19.489490509033203, 'step': 640},\n",
       "  {'loss': 0.8868200778961182, 'step': 641},\n",
       "  {'loss': 0.9243683815002441, 'step': 642},\n",
       "  {'loss': 0.6949335932731628, 'step': 643},\n",
       "  {'loss': 1.2368053197860718, 'step': 644},\n",
       "  {'loss': 0.8019768595695496, 'step': 645},\n",
       "  {'loss': 0.5500949025154114, 'step': 646},\n",
       "  {'loss': 0.6644084453582764, 'step': 647},\n",
       "  {'loss': 0.45428353548049927, 'step': 648},\n",
       "  {'loss': 0.9881837368011475, 'step': 649},\n",
       "  {'loss': 0.4131459891796112, 'step': 650},\n",
       "  {'loss': 0.677457869052887, 'step': 651},\n",
       "  {'loss': 0.49830442667007446, 'step': 652},\n",
       "  {'loss': 0.8560170531272888, 'step': 653},\n",
       "  {'loss': 0.43844449520111084, 'step': 654},\n",
       "  {'loss': 0.6354339122772217, 'step': 655},\n",
       "  {'loss': 0.5355058908462524, 'step': 656},\n",
       "  {'loss': 0.793455958366394, 'step': 657},\n",
       "  {'loss': 1.3429057598114014, 'step': 658},\n",
       "  {'loss': 0.5006605982780457, 'step': 659},\n",
       "  {'loss': 0.8358781337738037, 'step': 660},\n",
       "  {'loss': 0.59175044298172, 'step': 661},\n",
       "  {'loss': 0.6198670864105225, 'step': 662},\n",
       "  {'loss': 0.5572060346603394, 'step': 663},\n",
       "  {'loss': 0.7803148627281189, 'step': 664},\n",
       "  {'loss': 0.5623088479042053, 'step': 665},\n",
       "  {'loss': 0.439663827419281, 'step': 666},\n",
       "  {'loss': 0.5308903455734253, 'step': 667},\n",
       "  {'loss': 0.767507016658783, 'step': 668},\n",
       "  {'loss': 0.432860404253006, 'step': 669},\n",
       "  {'loss': 0.4690858721733093, 'step': 670},\n",
       "  {'loss': 0.6148799061775208, 'step': 671},\n",
       "  {'loss': 0.8443875908851624, 'step': 672},\n",
       "  {'loss': 0.7012970447540283, 'step': 673},\n",
       "  {'loss': 0.9880574941635132, 'step': 674},\n",
       "  {'loss': 0.5766430497169495, 'step': 675},\n",
       "  {'loss': 0.6704533696174622, 'step': 676},\n",
       "  {'loss': 0.2803158164024353, 'step': 677},\n",
       "  {'loss': 1.1130564212799072, 'step': 678},\n",
       "  {'loss': 0.4452439248561859, 'step': 679},\n",
       "  {'loss': 0.9199554324150085, 'step': 680},\n",
       "  {'loss': 0.5152594447135925, 'step': 681},\n",
       "  {'loss': 0.36927923560142517, 'step': 682},\n",
       "  {'loss': 0.28794994950294495, 'step': 683},\n",
       "  {'loss': 0.3465578258037567, 'step': 684},\n",
       "  {'loss': 0.2812144458293915, 'step': 685},\n",
       "  {'loss': 1.0849884748458862, 'step': 686},\n",
       "  {'loss': 2.5992958545684814, 'step': 687},\n",
       "  {'loss': 0.23617209494113922, 'step': 688},\n",
       "  {'loss': 0.3803195059299469, 'step': 689},\n",
       "  {'loss': 0.42460107803344727, 'step': 690},\n",
       "  {'loss': 0.8662545680999756, 'step': 691},\n",
       "  {'loss': 0.39664483070373535, 'step': 692},\n",
       "  {'loss': 0.42369192838668823, 'step': 693},\n",
       "  {'loss': 0.7609348297119141, 'step': 694},\n",
       "  {'loss': 1.460524559020996, 'step': 695},\n",
       "  {'loss': 0.4409123957157135, 'step': 696},\n",
       "  {'loss': 1.4076610803604126, 'step': 697},\n",
       "  {'loss': 0.5964810252189636, 'step': 698},\n",
       "  {'loss': 0.36843565106391907, 'step': 699},\n",
       "  {'loss': 1.0603539943695068, 'step': 700},\n",
       "  {'loss': 0.559246301651001, 'step': 701},\n",
       "  {'loss': 1.5822721719741821, 'step': 702},\n",
       "  {'loss': 0.3394053876399994, 'step': 703},\n",
       "  {'loss': 0.43195971846580505, 'step': 704},\n",
       "  {'loss': 0.5759754776954651, 'step': 705},\n",
       "  {'loss': 0.27164146304130554, 'step': 706},\n",
       "  {'loss': 0.3710402846336365, 'step': 707},\n",
       "  {'loss': 0.24979519844055176, 'step': 708},\n",
       "  {'loss': 0.5053808689117432, 'step': 709},\n",
       "  {'loss': 0.7429741621017456, 'step': 710},\n",
       "  {'loss': 0.9004222750663757, 'step': 711},\n",
       "  {'loss': 0.8541396856307983, 'step': 712},\n",
       "  {'loss': 0.39613211154937744, 'step': 713},\n",
       "  {'loss': 0.27452147006988525, 'step': 714},\n",
       "  {'loss': 0.6698262095451355, 'step': 715},\n",
       "  {'loss': 0.5938661694526672, 'step': 716},\n",
       "  {'loss': 0.3238430917263031, 'step': 717},\n",
       "  {'loss': 0.32645460963249207, 'step': 718},\n",
       "  {'loss': 0.4180532693862915, 'step': 719},\n",
       "  {'loss': 1.040277361869812, 'step': 720},\n",
       "  {'loss': 0.8574883341789246, 'step': 721},\n",
       "  {'loss': 0.3743986189365387, 'step': 722},\n",
       "  {'loss': 1.363307237625122, 'step': 723},\n",
       "  {'loss': 0.39638376235961914, 'step': 724},\n",
       "  {'loss': 0.509398341178894, 'step': 725},\n",
       "  {'loss': 0.5838057398796082, 'step': 726},\n",
       "  {'loss': 0.2577856481075287, 'step': 727},\n",
       "  {'loss': 0.6703871488571167, 'step': 728},\n",
       "  {'loss': 0.5050999522209167, 'step': 729},\n",
       "  {'loss': 0.6340802311897278, 'step': 730},\n",
       "  {'loss': 0.30769357085227966, 'step': 731},\n",
       "  {'loss': 0.23583631217479706, 'step': 732},\n",
       "  {'loss': 0.4876089096069336, 'step': 733},\n",
       "  {'loss': 0.18541106581687927, 'step': 734},\n",
       "  {'loss': 0.3040030002593994, 'step': 735},\n",
       "  {'loss': 0.36729514598846436, 'step': 736},\n",
       "  {'loss': 0.74992835521698, 'step': 737},\n",
       "  {'loss': 0.6144658923149109, 'step': 738},\n",
       "  {'loss': 0.5734508037567139, 'step': 739},\n",
       "  {'loss': 0.2619144320487976, 'step': 740},\n",
       "  {'loss': 0.2607194483280182, 'step': 741},\n",
       "  {'loss': 0.7782444357872009, 'step': 742},\n",
       "  {'loss': 0.39634889364242554, 'step': 743},\n",
       "  {'loss': 0.437075674533844, 'step': 744},\n",
       "  {'loss': 0.38194218277931213, 'step': 745},\n",
       "  {'loss': 0.9387771487236023, 'step': 746},\n",
       "  {'loss': 0.2768968939781189, 'step': 747},\n",
       "  {'loss': 0.7760699987411499, 'step': 748},\n",
       "  {'loss': 0.4280582666397095, 'step': 749},\n",
       "  {'loss': 0.865065336227417, 'step': 750},\n",
       "  {'loss': 0.23499363660812378, 'step': 751},\n",
       "  {'loss': 0.3680422008037567, 'step': 752},\n",
       "  {'loss': 0.3529619872570038, 'step': 753},\n",
       "  {'loss': 0.38984188437461853, 'step': 754},\n",
       "  {'loss': 0.33936357498168945, 'step': 755},\n",
       "  {'loss': 1.0452483892440796, 'step': 756},\n",
       "  {'loss': 0.20421136915683746, 'step': 757},\n",
       "  {'loss': 0.4400269091129303, 'step': 758},\n",
       "  {'loss': 0.3620809018611908, 'step': 759},\n",
       "  {'loss': 0.5185673832893372, 'step': 760},\n",
       "  {'loss': 0.21387717127799988, 'step': 761},\n",
       "  {'loss': 0.7311358451843262, 'step': 762},\n",
       "  {'loss': 0.5095377564430237, 'step': 763},\n",
       "  {'loss': 0.2923772931098938, 'step': 764},\n",
       "  {'loss': 0.25655001401901245, 'step': 765},\n",
       "  {'loss': 0.6374447345733643, 'step': 766},\n",
       "  {'loss': 0.4965948164463043, 'step': 767},\n",
       "  {'loss': 0.31786224246025085, 'step': 768},\n",
       "  {'loss': 0.22558337450027466, 'step': 769},\n",
       "  {'loss': 0.41976162791252136, 'step': 770},\n",
       "  {'loss': 0.44085603952407837, 'step': 771},\n",
       "  {'loss': 0.3047196865081787, 'step': 772},\n",
       "  {'loss': 0.20023775100708008, 'step': 773},\n",
       "  {'loss': 0.9391277432441711, 'step': 774},\n",
       "  {'loss': 0.5577089786529541, 'step': 775},\n",
       "  {'loss': 0.41536661982536316, 'step': 776},\n",
       "  {'loss': 0.4738510251045227, 'step': 777},\n",
       "  {'loss': 0.40583109855651855, 'step': 778},\n",
       "  {'loss': 0.6712096929550171, 'step': 779},\n",
       "  {'loss': 0.30475813150405884, 'step': 780},\n",
       "  {'loss': 0.5062022805213928, 'step': 781},\n",
       "  {'loss': 0.7537758946418762, 'step': 782},\n",
       "  {'loss': 0.30961930751800537, 'step': 783},\n",
       "  {'loss': 0.6350702047348022, 'step': 784},\n",
       "  {'loss': 0.2408771514892578, 'step': 785},\n",
       "  {'loss': 1.2620112895965576, 'step': 786},\n",
       "  {'loss': 0.7612396478652954, 'step': 787},\n",
       "  {'loss': 0.6459090709686279, 'step': 788},\n",
       "  {'loss': 1.0216097831726074, 'step': 789},\n",
       "  {'loss': 0.2340012490749359, 'step': 790},\n",
       "  {'loss': 0.6052542924880981, 'step': 791},\n",
       "  {'loss': 0.17341822385787964, 'step': 792},\n",
       "  {'loss': 0.3570055663585663, 'step': 793},\n",
       "  {'loss': 0.7206667065620422, 'step': 794},\n",
       "  {'loss': 0.7186253070831299, 'step': 795},\n",
       "  {'loss': 0.23908628523349762, 'step': 796},\n",
       "  {'loss': 0.40297219157218933, 'step': 797},\n",
       "  {'loss': 0.3831968605518341, 'step': 798},\n",
       "  {'loss': 55.75381851196289, 'step': 799},\n",
       "  {'loss': 0.9057345390319824, 'step': 800},\n",
       "  {'loss': 0.21603018045425415, 'step': 801},\n",
       "  {'loss': 0.4739799499511719, 'step': 802},\n",
       "  {'loss': 0.24184854328632355, 'step': 803},\n",
       "  {'loss': 0.7225924730300903, 'step': 804},\n",
       "  {'loss': 0.33124297857284546, 'step': 805},\n",
       "  {'loss': 0.7934934496879578, 'step': 806},\n",
       "  {'loss': 0.39734336733818054, 'step': 807},\n",
       "  {'loss': 0.3859296441078186, 'step': 808},\n",
       "  {'loss': 0.906320333480835, 'step': 809},\n",
       "  {'loss': 0.6016331911087036, 'step': 810},\n",
       "  {'loss': 1.2239373922348022, 'step': 811},\n",
       "  {'loss': 0.7514957189559937, 'step': 812},\n",
       "  {'loss': 0.17127327620983124, 'step': 813},\n",
       "  {'loss': 0.622401237487793, 'step': 814},\n",
       "  {'loss': 1.1950042247772217, 'step': 815},\n",
       "  {'loss': 3.247187614440918, 'step': 816},\n",
       "  {'loss': 1.0201647281646729, 'step': 817},\n",
       "  {'loss': 0.8195782899856567, 'step': 818},\n",
       "  {'loss': 0.17020323872566223, 'step': 819},\n",
       "  {'loss': 1.1128021478652954, 'step': 820},\n",
       "  {'loss': 0.9287267923355103, 'step': 821},\n",
       "  {'loss': 2.3823952674865723, 'step': 822},\n",
       "  {'loss': 0.3786923885345459, 'step': 823},\n",
       "  {'loss': 0.7619751691818237, 'step': 824},\n",
       "  {'loss': 0.7072976231575012, 'step': 825},\n",
       "  {'loss': 1.606144666671753, 'step': 826},\n",
       "  {'loss': 0.6645104885101318, 'step': 827},\n",
       "  {'loss': 0.41181057691574097, 'step': 828},\n",
       "  {'loss': 0.6263898611068726, 'step': 829},\n",
       "  {'loss': 0.34350258111953735, 'step': 830},\n",
       "  {'loss': 1.6171144247055054, 'step': 831},\n",
       "  {'loss': 0.1923523098230362, 'step': 832},\n",
       "  {'loss': 0.45947274565696716, 'step': 833},\n",
       "  {'loss': 0.5440824627876282, 'step': 834},\n",
       "  {'loss': 0.7767258286476135, 'step': 835},\n",
       "  {'loss': 0.8432822823524475, 'step': 836},\n",
       "  {'loss': 0.28502681851387024, 'step': 837},\n",
       "  {'loss': 0.8833937644958496, 'step': 838},\n",
       "  {'loss': 0.4786236882209778, 'step': 839},\n",
       "  {'loss': 0.3289147913455963, 'step': 840},\n",
       "  {'loss': 0.5780982375144958, 'step': 841},\n",
       "  {'loss': 0.31176263093948364, 'step': 842},\n",
       "  {'loss': 0.7986612319946289, 'step': 843},\n",
       "  {'loss': 0.3981179893016815, 'step': 844},\n",
       "  {'loss': 0.47540801763534546, 'step': 845},\n",
       "  {'loss': 0.2984562814235687, 'step': 846},\n",
       "  {'loss': 0.21778130531311035, 'step': 847},\n",
       "  {'loss': 0.8004893064498901, 'step': 848},\n",
       "  {'loss': 0.4412132799625397, 'step': 849},\n",
       "  {'loss': 0.2637365758419037, 'step': 850},\n",
       "  {'loss': 0.2577139437198639, 'step': 851},\n",
       "  {'loss': 0.6957377195358276, 'step': 852},\n",
       "  {'loss': 0.255375474691391, 'step': 853},\n",
       "  {'loss': 0.4930581748485565, 'step': 854},\n",
       "  {'loss': 0.5244945287704468, 'step': 855},\n",
       "  {'loss': 0.68045973777771, 'step': 856},\n",
       "  {'loss': 0.4461525082588196, 'step': 857},\n",
       "  {'loss': 0.2858887016773224, 'step': 858},\n",
       "  {'loss': 0.40817156434059143, 'step': 859},\n",
       "  {'loss': 0.3095382750034332, 'step': 860},\n",
       "  {'loss': 0.24151483178138733, 'step': 861},\n",
       "  {'loss': 0.42597800493240356, 'step': 862},\n",
       "  {'loss': 0.3499372601509094, 'step': 863},\n",
       "  {'loss': 0.2827050983905792, 'step': 864},\n",
       "  {'loss': 0.4673363268375397, 'step': 865},\n",
       "  {'loss': 0.3288096785545349, 'step': 866},\n",
       "  {'loss': 0.6787929534912109, 'step': 867},\n",
       "  {'loss': 1.4682059288024902, 'step': 868},\n",
       "  {'loss': 1.4724597930908203, 'step': 869},\n",
       "  {'loss': 0.25945931673049927, 'step': 870},\n",
       "  {'loss': 0.4486472010612488, 'step': 871},\n",
       "  {'loss': 0.3791939318180084, 'step': 872},\n",
       "  {'loss': 0.7361364960670471, 'step': 873},\n",
       "  {'loss': 0.15599100291728973, 'step': 874},\n",
       "  {'loss': 0.38863369822502136, 'step': 875},\n",
       "  {'loss': 0.33985310792922974, 'step': 876},\n",
       "  {'loss': 0.521580696105957, 'step': 877},\n",
       "  {'loss': 1.2774701118469238, 'step': 878},\n",
       "  {'loss': 0.9056981205940247, 'step': 879},\n",
       "  {'loss': 0.4872302711009979, 'step': 880},\n",
       "  {'loss': 0.4746112525463104, 'step': 881},\n",
       "  {'loss': 0.7012415528297424, 'step': 882},\n",
       "  {'loss': 0.5322908163070679, 'step': 883},\n",
       "  {'loss': 0.44981133937835693, 'step': 884},\n",
       "  {'loss': 1.355898380279541, 'step': 885},\n",
       "  {'loss': 0.36635804176330566, 'step': 886},\n",
       "  {'loss': 0.3104463219642639, 'step': 887},\n",
       "  {'loss': 0.6626530885696411, 'step': 888},\n",
       "  {'loss': 0.6415696144104004, 'step': 889},\n",
       "  {'loss': 0.4703935980796814, 'step': 890},\n",
       "  {'loss': 0.4030325412750244, 'step': 891},\n",
       "  {'loss': 0.6462138295173645, 'step': 892},\n",
       "  {'loss': 0.37100014090538025, 'step': 893},\n",
       "  {'loss': 0.20482327044010162, 'step': 894},\n",
       "  {'loss': 0.1723988652229309, 'step': 895},\n",
       "  {'loss': 0.2889339327812195, 'step': 896},\n",
       "  {'loss': 0.8581209778785706, 'step': 897},\n",
       "  {'loss': 0.37006086111068726, 'step': 898},\n",
       "  {'loss': 0.3104252219200134, 'step': 899},\n",
       "  {'loss': 0.4966840147972107, 'step': 900},\n",
       "  {'loss': 0.3625151515007019, 'step': 901},\n",
       "  {'loss': 0.2942603826522827, 'step': 902},\n",
       "  {'loss': 0.17445038259029388, 'step': 903},\n",
       "  {'loss': 0.5044057965278625, 'step': 904},\n",
       "  {'loss': 0.38021236658096313, 'step': 905},\n",
       "  {'loss': 0.303580641746521, 'step': 906},\n",
       "  {'loss': 0.2948857247829437, 'step': 907},\n",
       "  {'loss': 0.39294153451919556, 'step': 908},\n",
       "  {'loss': 0.960595965385437, 'step': 909},\n",
       "  {'loss': 0.6344872713088989, 'step': 910},\n",
       "  {'loss': 0.41920700669288635, 'step': 911},\n",
       "  {'loss': 1.0755226612091064, 'step': 912},\n",
       "  {'loss': 0.3747672736644745, 'step': 913},\n",
       "  {'loss': 0.5055370926856995, 'step': 914},\n",
       "  {'loss': 0.3316931128501892, 'step': 915},\n",
       "  {'loss': 0.40664008259773254, 'step': 916},\n",
       "  {'loss': 1.0900378227233887, 'step': 917},\n",
       "  {'loss': 0.7344258427619934, 'step': 918},\n",
       "  {'loss': 0.5192626118659973, 'step': 919},\n",
       "  {'loss': 1.3819586038589478, 'step': 920},\n",
       "  {'loss': 0.884196400642395, 'step': 921},\n",
       "  {'loss': 0.443815678358078, 'step': 922},\n",
       "  {'loss': 0.20050552487373352, 'step': 923},\n",
       "  {'loss': 0.41018515825271606, 'step': 924},\n",
       "  {'loss': 0.3882102370262146, 'step': 925},\n",
       "  {'loss': 0.15408872067928314, 'step': 926},\n",
       "  {'loss': 0.3447139263153076, 'step': 927},\n",
       "  {'loss': 0.8623026609420776, 'step': 928},\n",
       "  {'loss': 0.35564956068992615, 'step': 929},\n",
       "  {'loss': 0.45145031809806824, 'step': 930},\n",
       "  {'loss': 0.07636810839176178, 'step': 931},\n",
       "  {'loss': 0.432190477848053, 'step': 932},\n",
       "  {'loss': 0.2928306460380554, 'step': 933},\n",
       "  {'loss': 0.290364146232605, 'step': 934},\n",
       "  {'loss': 0.6293447613716125, 'step': 935},\n",
       "  {'loss': 0.8390325903892517, 'step': 936},\n",
       "  {'loss': 1.4007374048233032, 'step': 937},\n",
       "  {'loss': 0.1448703557252884, 'step': 938},\n",
       "  {'loss': 0.8038796186447144, 'step': 939},\n",
       "  {'loss': 0.4281215965747833, 'step': 940},\n",
       "  {'loss': 1.0206974744796753, 'step': 941},\n",
       "  {'loss': 0.9463562965393066, 'step': 942},\n",
       "  {'loss': 0.6090212464332581, 'step': 943},\n",
       "  {'loss': 0.22718670964241028, 'step': 944},\n",
       "  {'loss': 0.9597230553627014, 'step': 945},\n",
       "  {'loss': 0.360365629196167, 'step': 946},\n",
       "  {'loss': 0.9509721398353577, 'step': 947},\n",
       "  {'loss': 0.291233628988266, 'step': 948},\n",
       "  {'loss': 0.7456026077270508, 'step': 949},\n",
       "  {'loss': 0.5192266702651978, 'step': 950},\n",
       "  {'loss': 0.6853297352790833, 'step': 951},\n",
       "  {'loss': 0.7013043165206909, 'step': 952},\n",
       "  {'loss': 0.5263347029685974, 'step': 953},\n",
       "  {'loss': 0.560908854007721, 'step': 954},\n",
       "  {'loss': 0.8282231688499451, 'step': 955},\n",
       "  {'loss': 0.2907367944717407, 'step': 956},\n",
       "  {'loss': 0.6769118309020996, 'step': 957},\n",
       "  {'loss': 0.5517221689224243, 'step': 958},\n",
       "  {'loss': 0.4044533371925354, 'step': 959},\n",
       "  {'loss': 1.5665045976638794, 'step': 960},\n",
       "  {'loss': 0.21177348494529724, 'step': 961},\n",
       "  {'loss': 1.1526035070419312, 'step': 962},\n",
       "  {'loss': 0.23838521540164948, 'step': 963},\n",
       "  {'loss': 0.282450795173645, 'step': 964},\n",
       "  {'loss': 0.7026848793029785, 'step': 965},\n",
       "  {'loss': 0.30732157826423645, 'step': 966},\n",
       "  {'loss': 0.2205813229084015, 'step': 967},\n",
       "  {'loss': 0.29089686274528503, 'step': 968},\n",
       "  {'loss': 0.24821536242961884, 'step': 969},\n",
       "  {'loss': 0.37240713834762573, 'step': 970},\n",
       "  {'loss': 0.379038542509079, 'step': 971},\n",
       "  {'loss': 0.3313775956630707, 'step': 972},\n",
       "  {'loss': 0.1798771470785141, 'step': 973},\n",
       "  {'loss': 0.38106149435043335, 'step': 974},\n",
       "  {'loss': 0.31036996841430664, 'step': 975},\n",
       "  {'loss': 0.7374136447906494, 'step': 976},\n",
       "  {'loss': 0.34043723344802856, 'step': 977},\n",
       "  {'loss': 0.1834944486618042, 'step': 978},\n",
       "  {'loss': 0.8804362416267395, 'step': 979},\n",
       "  {'loss': 0.7408991456031799, 'step': 980},\n",
       "  {'loss': 0.8580878973007202, 'step': 981},\n",
       "  {'loss': 0.3443242311477661, 'step': 982},\n",
       "  {'loss': 0.812236487865448, 'step': 983},\n",
       "  {'loss': 0.6202483773231506, 'step': 984},\n",
       "  {'loss': 0.2695778012275696, 'step': 985},\n",
       "  {'loss': 0.3890535235404968, 'step': 986},\n",
       "  {'loss': 0.30556586384773254, 'step': 987},\n",
       "  {'loss': 0.29277944564819336, 'step': 988},\n",
       "  {'loss': 0.36144861578941345, 'step': 989},\n",
       "  {'loss': 0.15730300545692444, 'step': 990},\n",
       "  {'loss': 0.6632330417633057, 'step': 991},\n",
       "  {'loss': 0.34876304864883423, 'step': 992},\n",
       "  {'loss': 0.20908737182617188, 'step': 993},\n",
       "  {'loss': 0.2816961109638214, 'step': 994},\n",
       "  {'loss': 0.40690919756889343, 'step': 995},\n",
       "  {'loss': 0.8256484270095825, 'step': 996},\n",
       "  {'loss': 0.5382798314094543, 'step': 997},\n",
       "  {'loss': 0.5571562647819519, 'step': 998},\n",
       "  {'loss': 0.6789405941963196, 'step': 999},\n",
       "  ...],\n",
       " 'val': [{'loss': 7.050153756929824, 'step': 0},\n",
       "  {'loss': 0.6224363629729295, 'step': 726},\n",
       "  {'loss': 0.4549764582256148, 'step': 1452},\n",
       "  {'loss': 0.42447129957193186, 'step': 2178},\n",
       "  {'loss': 0.41263205514959067, 'step': 2904},\n",
       "  {'loss': 0.41227325212118054, 'step': 3630},\n",
       "  {'loss': 0.9031261094222384, 'step': 4356},\n",
       "  {'loss': 0.3959815608691578, 'step': 5082},\n",
       "  {'loss': 0.9623454976980844, 'step': 5808},\n",
       "  {'loss': 0.3867893593062547, 'step': 6534},\n",
       "  {'loss': 0.3826954967288439, 'step': 7260},\n",
       "  {'loss': 0.4110999833176698, 'step': 7986},\n",
       "  {'loss': 0.37124642144796277, 'step': 8712},\n",
       "  {'loss': 0.3684523397487057, 'step': 9438},\n",
       "  {'loss': 0.36875002763488074, 'step': 10164},\n",
       "  {'loss': 0.3602202113502282, 'step': 10890},\n",
       "  {'loss': 0.3572698551083892, 'step': 11616},\n",
       "  {'loss': 0.3537805730646307, 'step': 12342},\n",
       "  {'loss': 0.35025302202186803, 'step': 13068},\n",
       "  {'loss': 0.35193227724102905, 'step': 13794},\n",
       "  {'loss': 0.36106893121580447, 'step': 14520},\n",
       "  {'loss': 0.34656122696301167, 'step': 15246},\n",
       "  {'loss': 0.35473219416111956, 'step': 15972},\n",
       "  {'loss': 0.3447715913769135, 'step': 16698},\n",
       "  {'loss': 0.3416155790063468, 'step': 17424},\n",
       "  {'loss': 0.33770749265374234, 'step': 18150},\n",
       "  {'loss': 0.3385603892470687, 'step': 18876},\n",
       "  {'loss': 0.3447785011900604, 'step': 19602},\n",
       "  {'loss': 0.339640822384722, 'step': 20328},\n",
       "  {'loss': 0.349396940720968, 'step': 21054},\n",
       "  {'loss': 0.34111429835585033, 'step': 21780},\n",
       "  {'loss': 0.33666591546382785, 'step': 22506},\n",
       "  {'loss': 0.33440878691752096, 'step': 23232},\n",
       "  {'loss': 0.3412010097676072, 'step': 23958},\n",
       "  {'loss': 0.333943534319189, 'step': 24684},\n",
       "  {'loss': 0.3289261715532827, 'step': 25410},\n",
       "  {'loss': 0.32552139430252974, 'step': 26136},\n",
       "  {'loss': 0.33042691149248565, 'step': 26862},\n",
       "  {'loss': 0.32333013501541674, 'step': 27588},\n",
       "  {'loss': 0.32485858746611873, 'step': 28314},\n",
       "  {'loss': 0.33179408779814223, 'step': 29040},\n",
       "  {'loss': 0.32970177551562135, 'step': 29766},\n",
       "  {'loss': 0.3234419340560259, 'step': 30492},\n",
       "  {'loss': 0.3237826133470151, 'step': 31218},\n",
       "  {'loss': 0.3213927251063595, 'step': 31944},\n",
       "  {'loss': 0.32369562276939223, 'step': 32670},\n",
       "  {'loss': 0.3331123491333536, 'step': 33396},\n",
       "  {'loss': 0.3209466317991826, 'step': 34122},\n",
       "  {'loss': 0.3273882975509344, 'step': 34848},\n",
       "  {'loss': 0.32981348822801565, 'step': 35574},\n",
       "  {'loss': 0.3183458528427546, 'step': 36300},\n",
       "  {'loss': 0.31690305303628286, 'step': 37026},\n",
       "  {'loss': 0.31333952734231457, 'step': 37752},\n",
       "  {'loss': 0.3155708683054309, 'step': 38478},\n",
       "  {'loss': 0.31895400888540526, 'step': 39204},\n",
       "  {'loss': 0.3192749838075362, 'step': 39930},\n",
       "  {'loss': 0.3199796082128671, 'step': 40656},\n",
       "  {'loss': 0.3151639149147124, 'step': 41382},\n",
       "  {'loss': 0.31231872908278435, 'step': 42108},\n",
       "  {'loss': 0.32014814166983296, 'step': 42834},\n",
       "  {'loss': 0.31146131645241554, 'step': 43560},\n",
       "  {'loss': 0.31663395627594193, 'step': 44286},\n",
       "  {'loss': 0.30891045838717585, 'step': 45012},\n",
       "  {'loss': 0.3173803709108721, 'step': 45738},\n",
       "  {'loss': 0.3244409295306964, 'step': 46464},\n",
       "  {'loss': 0.3129544881565019, 'step': 47190},\n",
       "  {'loss': 0.31496681676300103, 'step': 47916},\n",
       "  {'loss': 0.32241643875960474, 'step': 48642},\n",
       "  {'loss': 0.3158129684565481, 'step': 49368},\n",
       "  {'loss': 0.31810514100881154, 'step': 50094},\n",
       "  {'loss': 0.31290420762086213, 'step': 50820},\n",
       "  {'loss': 0.3102882153947245, 'step': 51546},\n",
       "  {'loss': 0.32131631152073215, 'step': 52272}]}"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 24
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-25T11:13:09.304496Z",
     "start_time": "2025-01-25T11:13:09.184542Z"
    }
   },
   "source": [
    "#画线要注意的是损失是不一定在零到1之间的\n",
    "def plot_learning_curves(record_dict, sample_step=500):\n",
    "    # build DataFrame\n",
    "    train_df = pd.DataFrame(record_dict[\"train\"]).set_index(\"step\").iloc[::sample_step]\n",
    "    val_df = pd.DataFrame(record_dict[\"val\"]).set_index(\"step\")\n",
    "\n",
    "    # plot\n",
    "    for idx, item in enumerate(train_df.columns):\n",
    "        plt.plot(train_df.index, train_df[item], label=f\"train_{item}\")\n",
    "        plt.plot(val_df.index, val_df[item], label=f\"val_{item}\")\n",
    "        plt.grid()\n",
    "        plt.legend()\n",
    "        # plt.xticks(range(0, train_df.index[-1], 10*sample_step), range(0, train_df.index[-1], 10*sample_step))\n",
    "        plt.xlabel(\"step\")\n",
    "\n",
    "        plt.show()\n",
    "\n",
    "plot_learning_curves(record)  #横坐标是 steps"
   ],
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ],
      "image/png": "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"
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "execution_count": 25
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 测试集"
   ]
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-01-25T11:13:42.766225Z",
     "start_time": "2025-01-25T11:13:42.701988Z"
    }
   },
   "source": [
    "model.eval()\n",
    "loss = evaluating(model, test_loader, loss_fct)\n",
    "print(f\"loss:     {loss:.4f}\")"
   ],
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "loss:     0.3216\n"
     ]
    }
   ],
   "execution_count": 26
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "pytorch",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.8"
  },
  "orig_nbformat": 4
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
